I'm working on a very simple react app, but when I try to use router in always makes pathname with first letter Capital case and I don't have any idea why.
app.js
import React from "react";
import ReactDOM from "react-dom";
import Layout from "./pages/Layout"
import Basket from "./pages/Basket"
import { Router, Route, IndexRoute, hashHistory } from "react-router"
const app = document.getElementById('app');
ReactDOM.render(
<Router history={hashHistory}>
<Route path="/" component={Layout}>
<IndexRoute component={ItemsList}></IndexRoute>
<Route path="basket" name="basket" component={Basket}></Route>
</Route>
</Router>,
app);
Header.js
import React from "react";
import { Link } from "react-router"
export default class Header extends React.Component {
render() {
const { location } = this.props;
const basketClass = location.pathname.match(/^\/basket/) ? "active" : "";
return (
<header>
<nav class="navbar navbar-default">
<div class="container">
<ul class="nav navbar-nav">
<li class={inventoryListClass}><Link to="/">Inventory</Link></li>
<li class={basketClass}><Link to="basket">Basket</Link></li>
</ul>
</div>
</nav>
</header>
);
}
}
does anyone now why it uses capital letter "/Basket" when I explicitly specified "basket" in route parameter.
thanks.
Layout.js
import React from "react";
import Footer from "./Footer";
import Header from "./Header";
export default class Layout extends React.Component {
render() {
const { location } = this.props
return (
<div>
<Header location={location} />
<div class="container">
{this.props.children}
</div>
<Footer />
</div>
);
}
}
Ok so I found the problem. I put capital capital "B" in <link to=Basketthis line in my header.js
<li class={basketClass}><Link to="Basket">Basket</Link></li>
So it was just a type. Sorry guys.
You don't have to check for active routes, by the way, there is activeClassName="active" which does the same.
Related
Header Component
import React from "react";
import { BrowserRouter as Router, Link } from "react-router-dom";
import { ReactComponent as Logo } from "../../asset/crown.svg";
import "./header.scss";
const Header = () => {
return (
<div className='header'>
<Router>
<Link exact className='logo-container' to='/'>
<Logo className='logo' />
</Link>
<div className='options'>
<Link className='option' to='/shop'>
SHOP
</Link>
</div>
</Router>
</div>
);
};
export default Header;
This is my header Component in which I am using Link tag but these tags are changing the URL in the Search Bar but not actually rendering the components.
You don't need the Router inside the Header Component...You can just use Link and then in your App.js setup the Route to the Component. Like So..
App.Js
import React from "react";
import { BrowserRouter as Router, Link } from "react-router-dom";
import { ReactComponent as Logo } from "../../asset/crown.svg";
import "./header.scss";
const Header = () => {
return (
<div className='header'>
<ul>
<li className='logo-container'>
<Link to='/'>
<Logo className='logo' />
</Link>
</li>
<li>
<Link to="/shop">
SHOP
</Link>
</li>
</div>
);
};
export default Header;
//APP COMPONENT
import React from "react";
import { BrowserRouter as Router,Switch, Route } from "react-router-dom";
const App = () => {
return (
<Router>
<Switch>
<Route exact path="/" component="Home">
<Route path="/shop" component="shop">
</Switch>
</Router>
);
};
export default App;
Make sure not to use BrowserRoute inside BrowserRouter.
e.g: when you place a component inside a component it's not JSX there it gets converted to HTML and can cause an error.
I'm working on a React web application using React router.
In my App.js file i have imported header and home component.
In home component i have 2 components called Onlinebanks and Creditcard that i imported from online-banks.js and creditcard.js files.
When the user clicks link buttons in home.js component, the Onlinebanks and Creditcard components should render.
Instead i am getting an error called Error: Invariant failed: You should not use < Link> outside a < Router>.
Why it's not working?
INDEX.JS
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
ReactDOM.render(<App />, document.getElementById('root'));
APP.JS
import React, { Component } from 'react';
import './App.css';
import Header from './components/header';
import Home from './components/home';
class Routes extends Component {
constructor(props){
super(props);
this.state = {
};
}
render(){
return (
<div className="wrapper">
<Header/>
<Home/>
</div>
);
}
}
export default Routes;
HOME.JS
import React from 'react';
import { Route, Switch, Link } from 'react-router-dom';
import Onlinebanks from './online-banks';
import Creditcard from './creditcard';
const Home = (props) => {
return (
<div className="section">
<div className="main-page">
<div className="tab-container">
<div className="tab-btns">
<Link to="/">
<div className="online-bank-btn">
Online pangad
</div>
</Link>
<Link to="/creditcard">
<div className="creditcard-btn">
Krediitkaart
</div>
</Link>
</div>
<Switch>
<Route path="/" exact component={Onlinebanks}/>
<Route path="/creditcard" exact component={Creditcard}/>
</Switch>
</div>
</div>
</div>
)
}
export default Home;
ONLINE-BANKS.JS
import React from 'react';
const Onlinebanks = (props) => {
return (
<div className="banks-container">
<input type="button" value="Pay" className="pay-btn" id="online-banks-pay"></input>
</div>
)
}
export default Onlinebanks;
CREDITCARD.JS
import React from 'react';
const Creditcard = (props) => {
return (
<div className="Creditcard-container">
<input type="button" value="Pay" className="pay-btn" id="creditcard-pay"></input>
</div>
)
}
export default Creditcard;
I don't see anywhere in your code where you imported BrowserRouter from react-router-dom which should wrap all the other components rendered by your top level componet (app.js) or entirely wrap the app component. so, first import { BrowserRouter as Router } from "react-router-dom" in index.js, then wrap App component with Router as follows
ReactDOM.render(<Router> <App /> </Router>, document.getElementById("root"));
alternatively you can wrap the retun statment in app.js with Router as follows after importing BrowserRouter as Router
return (
<Router>
<div className="wrapper">
<Header/>
<Home/>
</div>
</Router>
);
<Router> is an HOC component, so you need to use it at the top most level possible. Suggestion would be to create a separate Router component and use it within App.js file above div tag
<CustomRouter>
<div className="wrapper">
<Header/>
<Home/>
</div>
</CustomRouter>
you need to better understand how react-router-dom works.
visit here for complete routing guide react-router-dom
i found some major missings in your app.js file.
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route path="/about">
<About />
</Route>
<Route path="/dashboard">
<Dashboard />
</Route>
</Switch>
i don't see this method in your app.js .
So I am new to ReactJS and is trying to figure it things how to have an app with a different header for the login page and then another header once the user was logged in.
I only want to have the very first page to have the LoginHeader and then the PostHeader as the main header once they get authenticated.
However, when I am on the my login page, whenever I click the sign in button I automatically get taken to my PostHeader page even though I routed my correct link. Everything in the PostHeader works fine, like when I click Home and Create they return the pages they are supposed.
My code is down below
index.js
import React from 'react';
import createHistory from 'history/createBrowserHistory';
import ReactDOM from 'react-dom';
import { Route, Switch, Router } from 'react-router-dom';
import Header from "./_components/header/header";
ReactDOM.render(
<Router history={createHistory()}>
<div>
<Header />
</div>
</Router>,
document.getElementById('root'),
);
Header.js
import React, {Component} from 'react';
import {Link,Route,withRouter, Switch, } from 'react-router-dom';
import PostHeader from './PostHeader';
import LoginHeader from './LoginHeader';
class Header extends Component{
render(){
if (window.location.pathname === '/') {
return(
<LoginHeader />
);
};
return(
<PostHeader />
);
}
}
export default Header;
LoginHeader.js
import React, {Component} from 'react';
import {Link,Route,withRouter, Switch} from 'react-router-dom';
import SignIn from '../signin/signin';
import TopProjects from '../create_projects/top_projects';
class LoginHeader extends Component{
render(){
return(
<div className="container">
<div>
<h3>The Web App</h3>
<nav>
<ul>
<li><Link to="/sign-in">Sign In?</Link></li>
<li><Link to="/top-projects">Top Projects</Link></li>
</ul>
</nav>
<hr />
</div>
<Switch>
<Route exact path="/sign-in" component={SignIn}/>
<Route path="/top-projects" component={TopProjects} />
</Switch>
</div>
);
}
}
export default LoginHeader;
PostHeader.js
import React, {Component} from 'react';
import {Link,Route} from 'react-router-dom';
import Home from '../home/home';
import CreateProjects from '../create_projects/create_projects';
class PostHeader extends Component{
render(){
return(
<div className="container">
<div>
<h3>The Web App</h3>
<nav>
<ul>
<li><Link to="/home">Home</Link></li>
<li><Link to="/create-projects">Create</Link></li>
</ul>
</nav>
<hr />
</div>
<Route path="/home" component={Home}/>
<Route path="/create-projects" component={CreateProjects} />
</div>
);
}
}
export default PostHeader;
I just want to have different headers for some pages.
That's because in your Header.js, you are only rendering the LoginHeader if you are in the root route.
if (window.location.pathname === '/') {
return(
<LoginHeader />
);
};
So when you click the sign in button, it redirects you to /sign-in, thus when Header is re-rendered, the condition will fall on the else statement which returns the PostHeader.
js and am using react-router-dom.
Say I have 2 files - 1. dashboard.js file
import React, { Component } from 'react';
import {Switch, Route, Link} from 'react-router-dom';
import WYSIWYG from './editor/wysiwyg';
export default class Dashboard extends Component{
render(){
return(
<div className="wrapper">
<Switch>
<Route exact path="/wysiwyg" component={WYSIWYG}/>
</Switch>
<ul id="DASHBOARD-MENU">
<li><Link to={{ pathname: '/wysiwyg'}}>WYSIWYG</Link></li>
</ul>
</div>
);
}
}
Note the ul with id="DASHBOARD-MENU" above
2nd - wysiwyg.js file
import React, { Component } from 'react';
export default class Wysiwyg extends Component{
render(){
return(
<div id="WYSIWYG-CONTAINER">
</div>
);
}
}
Note the div with id="WYSIWYG-CONTAINER" in the above snippet
My problem is:
After redirection to WYSIWYG container from my dashboard, I can still see the - <ul id="DASHBOARD-MENU" .. rendered below the <div id="WYSIWYG-CONTAINER ...
What I understood - is the component WYSIWYG is rendered replacing <Route declared in my dashboard.js file.
What I want:
I don't want the "DASHBOARD-MENU" element to render in my "WYSIWYG" page.
Is it possible?
The desired behavior can be obtained by considering both as different routes, and hence rendering only one of them depending on the path:
import React, { Component } from 'react';
import {Switch, Route, Link} from 'react-router-dom';
import WYSIWYG from './editor/wysiwyg';
const Dashboard = () => (
<ul id="DASHBOARD-MENU">
<li><Link to={{ pathname: '/wysiwyg'}}>WYSIWYG</Link></li>
</ul>
);
export default class Dashboard extends Component{
render(){
return(
<div className="wrapper">
<Switch>
<Route exact path="/" component={Dashboard} />
<Route exact path="/wysiwyg" component={WYSIWYG}/>
</Switch>
</div>
);
}
}
I have a repo at https://bitbucket.org/codyc54321/anthony-project-react
I have the homepage showing links, and when you click the links react-router works. But the text of the component is not showing up, like <div>Login page</div>, <div>Homepage</div>, etc.
index.js:
import React from 'react';
import ReactDOM from 'react-dom';
import { Router, Route, Link, IndexRoute, browserHistory } from 'react-router';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import reducers from './reducers';
import Nav from './Nav';
import Home from './components/Home';
import Login from './components/Login';
import SignupMain from './components/SignupMain';
const createStoreWithMiddleware = applyMiddleware()(createStore);
ReactDOM.render(
(
<Provider store={createStoreWithMiddleware(reducers)}>
<Router history={browserHistory}>
<Route path="/" component={Nav}>
<IndexRoute component={Home}/>
<Route path='/login' component={Login}/>
<Route path='/signup-main' component={SignupMain}/>
</Route>
</Router>
</Provider>
), document.querySelector('.container'));
Nav.js:
import React from 'react';
import { Link } from 'react-router';
export default class Nav extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<nav className="navbar navbar-default">
<div className="container-fluid">
<div className="navbar-header navbar-brand">
Home
</div>
</div>
<div id="navbar" className="navbar-right">
<ul className="nav navbar-nav">
<li><Link activeClassName="active" to="/" onlyActiveOnIndex>Home</Link></li>
<li><Link activeClassName="active" to="/login" onlyActiveOnIndex>Login</Link></li>
<li><Link activeClassName="active" to="/signup-main" onlyActiveOnIndex>Signup</Link></li>
</ul>
</div>
</nav>
</div>
)
}
}
// export Nav as default;
components/Home.js:
import React, { Component } from 'react';
export default class Home extends Component {
render() {
return (
<div>Homepage</div>
);
}
}
Why aren't these components showing up on the page?
Since your other routes are nested inside the route for 'Nav' component, it should render its children somewhere. For that, you have to put this.props.children where you want to render nested components in JSX of Nav component.
export default class Nav extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<nav className="navbar navbar-default">
<div className="container-fluid">
<div className="navbar-header navbar-brand">
Home
</div>
</div>
<div id="navbar" className="navbar-right">
<ul className="nav navbar-nav">
<li><Link activeClassName="active" to="/" onlyActiveOnIndex>Home</Link></li>
<li><Link activeClassName="active" to="/login" onlyActiveOnIndex>Login</Link></li>
<li><Link activeClassName="active" to="/signup-main" onlyActiveOnIndex>Signup</Link></li>
</ul>
</div>
</nav>
<div>{this.props.children}</div>
</div>
)
}
}