I would like to make a navbar with different Links to different routes. In another file, I have the react-router stuff in order to change the website. But when I press on the links it works but only if I reload afterward.
The head file:
export default function Head(props){
return(
<Router>
<div className="Head">
<div className="HeadItemFirst">bwftp</div>
<div className="HeadPaths">
<Link className="HeadItem" to="/"><div>Start</div></Link>
<Link className="HeadItem" to="/about"><div>about</div></Link>
<Link className="HeadItem" to="/settings"><div>Settings</div></Link>
</div>
</div>
</Router>
)
}
And the App file:
export default function App(){
return(
<div className="App">
<Head />{/* Here are all the links in a navbar stored */}
<Body />
<Foot />
<Router>
<Switch>
<Route path="/" exact component={Home}/>
<Route path="/about" exact component={About}/>
<Route path="/settings" exact component={Settings}/>
<Route render={()=>(<h1>404</h1>)}/>
</Switch>
</Router>
</div>
)
}
You need not use multiple router instances in your Application. Instead have one at the topmost parent level. If you use multiple Routes, the Link components inside Head will communicate with the Router component inside Head only and will not relay the information of route change to Router in App
Also if you render Head as a default Route it will receive all props from Route and will ensure smooth functioning of the Routes
export default function Head(props){
return(
<div className="Head">
<div className="HeadItemFirst">bwftp</div>
<div className="HeadPaths">
<Link className="HeadItem" to="/"><div>Start</div></Link>
<Link className="HeadItem" to="/about"><div>about</div></Link>
<Link className="HeadItem" to="/settings"><div>Settings</div></Link>
</div>
</div>
)
}
export default function App(){
return(
<Router>
<div className="App">
<Route component={Head} /> //Render as a default route so that it gets route params
<Body />
<Foot />
<Switch>
<Route path="/" exact component={Home}/>
<Route path="/about" exact component={About}/>
<Route path="/settings" exact component={Settings}/>
<Route render={()=>(<h1>404</h1>)}/>
</Switch>
</div>
</Router>
)
}
Related
I have problem with common header in react js.
Currently login route is displaying common header and i dont want to show on my login page. If i go to contacts page than its showing common header which is perfect
import "./styles/App.scss";
import Navbar from "./components/elements/Navbar";
import Contacts from "./components/contacts/Contacts";
import { Provider } from "react-redux";
import store from "./store";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import AddContact from "./components/contacts/AddContact";
import EditContact from "./components/contacts/EditContact";
import Login from "./components/login/Login";
import Logout from "./components/logout/Logout";
function App(props) {
return (
<Provider store={ store }>
<Router>
<div className="App">
{props.location.pathname !== '/login' ? <Navbar/> : null}
<Route exact path="/login" component={ Login } />
<div className="container">
<div className="py-3">
<Switch>
<Route exact path="/" component={ Contacts } />
<Route exact path="/logout" component={ Logout } />
<Route exact path="/contacts/add" component={ AddContact } />
<Route
exact
path="/contacts/edit/:id"
component={ EditContact }
/>
</Switch>
</div>
</div>
</div>
</Router>
</Provider>
);
}
export default App;
[1]: https://i.stack.imgur.com/7V0qi.png
I think you meant to create Links in NavBar, not declare the Routes:
<Router>
<div className="App">
<div className="container">
<div className="py-3">
<Switch>
<Route exact path="/login" component={Login} />
<Route>
<Navbar />
<Switch>
<PrivateRoute exact path="/" component={Contacts} />
<PrivateRoute exact path="/logout" component={Logout} />
<PrivateRoute exact path="/contacts/add" component={AddContact} />
<PrivateRoute
exact
path="/contacts/edit/:id"
component={EditContact}
/>
</Switch>
</Route>
</Switch>
</div>
</div>
</div>
</Router>
NavBar:
function Navbar() {
const someId = 123 // example
return (
<>
<Link to="/">Login</Link>
<Link to="/logout">Logout</Link>
<Link to="/contacts/add">Add Contacts</Link>
<Link to={`/contacts/edit/${someId}`}>Edit Contact</Link>
</>
)
}
After this, you are most likely to be looking for authentication. I recently wrote an answer on authenticated or protected routes i.e. PrivateRoute.
Also, note that All children of a Switch should be Route or Redirect elements.
You can only show the <Navbar/> when it's not the login page and you need to keep the login page inside the switch for the pages to work.
return (
<Provider store={ store }>
<Router>
<div className="App">
{props.location.pathname !== '/login' ? <Navbar/> : null}
<div className="container">
<div className="py-3">
<Switch>
<Route exact path="/login" component={ Login } />
<Route exact path="/" component={ Contacts } />
<Route exact path="/logout" component={ Logout } />
<Route exact path="/contacts/add" component={ AddContact } />
<Route
exact
path="/contacts/edit/:id"
component={ EditContact }
/>
</Switch>
</div>
</div>
</div>
</Router>
</Provider>
);
consider the following example, I have a login page and an admin page. After logging in we will be redirected to admin page.
The admin page is shown as follows.
Desired behaviour: To render cars component in the admin component itself
Actual behaviour: On clicking cars or bikes component they are being rendered on a different page.
code is as follows
App.js
//imports here
function App() {
return(
<Router>
<Switch>
<Route exact path="/" component={Login} />
<Route exact path="/admin" component={Admin} />
<Route exact path="/cars" component={Cars} />
<Route exact path="/bikes" component={Bikes} />
</Switch>
</Router>
);
}
Admin.js
//imports here
const Admin = () => {
return (
<Fragment>
<div className="is-flex">
<Sidebar />
<Navbar />
</div>
</Fragment>
);
};
navbar.js
// imports here
const Sidebar = () => {
return (
<aside className="aside">
<p className="menu-label">Test Routes</p>
<ul className="menu-list">
<li>
<Link to="/cars">Cars</Link>
</li>
<li>
<Link to="/bikes">Bikes</Link>
</li>
</ul>
</aside>
);
};
Using react-router-dom ^5.1.2
Tried this but not able to understand what I missed? how to solve this problem?
Move your default route to the bottom of the stack. i.e.
function App() {
return(
<Router>
<Switch>
<Route path="/admin" component={Admin} />
<Route path="/cars" component={Cars} />
<Route path="/bikes" component={Bikes} />
<Route exact path="/" component={Login} />
</Switch>
</Router>
);
}
I have a react application in which I have wrapped layout components for the other routes, the thing is when I click the links present in the sidebar(part of layout) they are not being rendered on the screen, here is my code.
App.js
//Imports here
<Provider store={store}>
<Router>
<Switch>
<Layout>
<Route exact path="/admin" render={() => <Admin />} />
<Route exact path="/employees" render={() => <Employees />} />
<Route exact path="/profile" component={Profile} />
</Layout>
<Switch>
</Router>
</Provider>
Layout.js
//imports here
//styling here
<Link to='/employees' />
// and likewise for rest of the routes
When clicking the links ie, employees or profile they aren't being rendered, tried console.log to see if my layout was obstructing that, but no use. Please help me
It should be inside the Switch component but you can wrap it with a Layout component like that.
const Headers = () => (
<Layout>
<ul>
<li>
<Link to="/admin">Admin</Link>
</li>
<li>
<Link to="/profile">Profile</Link>
</li>
<li>
<Link to="/employees">Employees</Link>
</li>
</ul>
</Layout>
);
function App() {
return (
<Router>
<Layout>
<Header></Header>
<Switch>
<Route exact path="/admin" render={() => <Admin />} />
<Route exact path="/employees" render={() => <Employees/>}/>
<Route exact path="/profile" component={Profile} />
</Switch>
</Layout>
</Router>
);
}
If your URL is changing but the content is not being rendered, the problem is this, apart from wrapping the Routes as mentioned in #G.aziz 's answer since the routes are children WRT layout components we have to use {props.children} inside the layout component to render the content like so...
Layout.jsx
<div>
<Sidebar />
<Navbar />
{props.children} // here we are rendering the routes which we mentioned in the switch component in App.js
</div>
For me this solution fixed. Also please refer this question for further information. React-router v4, URL changing but component doesn't render
I have some routes which I have added header, div and sidemenu .
Outside of these I have added 'Page Not Found ' Route. But when I hit invalid URL it's not showing 'Page Not Found' page
I have tried putting all routes together inside the 'div' but I don't require these div, header, sidemenu for 'Page Not Found' page
<Switch>
<Route path="/" exact component={LoginPage} />
<Route path="/ShowReport" component={ShowReport} />
<div className="container-fluid py-5">
<Header />
<Notify />
<div className="row justify-content-center pt-2">
<Sidemenu />
<Route path="/test" component={Test} />
<Route path="/home" component={HomePage} />
</div>
</div>
<Route component={NotFoundPage} />
</Switch>
Expected Result is: When I hit invalid URL should show page not found without header, sidemnu.
You are using it the wrong way. Try it this way:
// import
import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";
// your class's return
return (
<Router>
<Switch>
<Route path="/" exact component={LoginPage} />
<Route path="/ShowReport" component={ShowReport} />
<div className="container-fluid py-5">
<Header />
<Notify />
<div className="row justify-content-center pt-2">
<Sidemenu />
<Route path="/test" component={Test} />
<Route path="/home" component={HomePage} />
</div>
</div>
<Route component={NotFoundPage} />
</Switch>
</Router>
);
I've tried your example here in sandbox: https://reacttraining.com/react-router/web/example/basic and got Invariant failed: You should not use <Switch> outside a <Router> error.
Try to wrap your Switch with Router imported like:
import { BrowserRouter as Router } from 'react-router-dom';
In the main example for routing a No-Match, the Switch element is wrapped in a Router element like this:
<Router>
<Switch>
<Route path="/" exact component={LoginPage} />
<Route path="/ShowReport" component={ShowReport} />
<Route component={NotFoundPage} />
</Switch>
</Router>
If this still does not solve your problem, try temporarily pasting <Route component={NotFoundPage} /> above the div, does this still show an empty page or does this change anything.
If this causes the notfoundpage to appear, you are passing an unknown prop in your original code (possibly by passing styling?).
I am using React for a small web-app. It has a basic 5 page website layout. (Home|About|Contact|Press|Shows) so I wanted to use an app template that just displays a menu, the header and the footer, and the {props.children} would be the React Router's route component. To achieve this, I used the following code. Assume all the imports are there...
Here is my router code:
export default (props) => {
return (
<Router history={ hashHistory }>
<Route path="/" component={ Template }>
<IndexRoute component={ Home }></IndexRoute>
<Route path="about" component={ About }></Route>
<Route path="music" component={ Music }></Route>
<Route path="store" component={ Store }></Route>
<Route path="shows" component={ Shows }></Route>
<Route path="contact" component={ Contact }></Route>
</Route>
</Router>
);
}
Now here is my template:
export default ( props ) => {
return (
<div className="container">
<Header />
<Menu />
{ props.children }
<Footer />
</div>
);
}
I know something is wrong, b/c without CSS magic, a:active is always HOME and any other active pages. I.E. if I click About, then both Home and About are active. How can I correctly use an index route, or should I even use an index route in this simple of an app? If not, then how else can I use a template like the one I have and pass in a page as a component in a different way?
Update: Here is my Menu.js file...
const Menu = () => {
return (
<div>
<nav>
<Link activeClassName="nav-active" to="/">Home</Link>
<Link activeClassName="nav-active" to="about">About</Link>
<Link activeClassName="nav-active" to="music">Music</Link>
<Link activeClassName="nav-active" to="shows">Shows</Link>
<Link activeClassName="nav-active" to="store">Store</Link>
<Link activeClassName="nav-active" to="contact">Contact</Link>
</nav>
<hr className="line" />
</div>
);
}
export default Menu;
for index route you should use IndexLink comp , otherwise 'Home' will be active allways
import {Link,IndexLink} from 'react-router';
<IndexLink activeClassName="nav-active" to="/">Home</IndexLink>
<Link activeClassName="nav-active" to="about">About</Link>
<Link activeClassName="nav-active" to="music">Music</Link>
...