One of the most frustrating thing about clicking on blog posts is having to scroll through people's long winded explanations of stuff when you can just put the answer at the top. Here's how you do the thing in the title:
<Router>
<NavLink to="/homepage">Homepage</NavLink>
<Route path="/homepage" render={props =>
(<Homepage {...props} pieceOfState={this.state.pieceOfState}/>)
}/>
</Router>
If you want details on that, please feel free to read on :)
The Router itself you can put in whatever place you want -- but it makes the most sense to pick a pretty top-level part of your app, so usually in the render method of your App.js file. As you can see above, the NavLink we are using points to the homepage of this particular site or app, and the route is the driving force which will actually do the work of rendering the component. If you don't need to pass the component any state, you would usually just see the router like so:
<Route path='/homepage' component={Homepage} />
But in React, passing state (or helper methods) is where all the power comes from -- it's what makes React so reactive. So you will want to use the first code snippet to get the functionality you want. The Route path in that code is using the render method to pass an inline function which will render the Homepage -- you may be wondering, why can't we just pass an inline function using the regular component method from snippet #2 and get the same result? The answer is that the component method will actually unmount and remount the entire component every time the state changes if you use an inline function with it. This creates an unnecessarily energy-expensive program when you could just use the neat render method that the friendly React devs intended you to use.
Now that that part's out of the way, here are the aforementioned Other Fun Things:
1. Passing the whole dang state
Sometimes, when writing in React, it's hard to keep the code DRY. You may find yourself writing this.state a ton of times while passing specific state pieces to the components you want. A fun little tip to help avoid that issue: you can pass the whole dang state over without specifying pieces. It looks like this:
<Homepage state={this.state}/>
That's pretty straight-forward. That's pretty state-forward? At any rate, you can then access the state pieces inside of that component by using this.props.state.pieceOfState.
2. Active links
Stylizing a link so that it responds when a user is on the associated page has never been easier. You can simply give the NavLink a class of activestyle (along with whatever CSS you want to occur) like so:
<NavLink to='/homepage' activeStyle={{fontWeight: "bold", color: 'blue'}}>Homepage</NavLink>
React will handle listening for which page the user is on.
3. Rendering a 404
Sometimes the users of your site will get wayward and decide that they can probably guess the available paths, so they will just type that path in expecting to see it come up. React is nice, and it won't break your site, but it won't tell the user that the page doesn't exist. To render a 404, it's useful to group your routes with a Switch tag.
<Switch>
<Route path='/homepage' component={Homepage}/>
<Route path='/profile' component={Profile}/>
<Route path='/seaturtles' component={Seaturtles}/>
<Route component={NoMatch}/>
</Switch>
In the above, the component "NoMatch" is not given a route, so all routes which are not defined will render the component, which you can build out to render whatever you want your 404 page to look like. You can put anything there. An image of Johnny Bravo. A link to the Wikipedia page on 404's. A never ending scroll loop of the Constitution. The world is your oyster.
4. Redirects
Intuitively, if your user is logged in, you won't want them to be able to navigate to the '/signin' page. BUT, you also don't want them to see a 404 page there. It's time to implement a redirect. This is accomplished by specifying another Route to '/signin' and giving it the instructions to render a Redirect. Observe:
<Route path="/signin" render={()=> (<Redirect to='/search'/>)}/>
This code shows the Route using the same render method as with passing props, but without the props themselves. The anonymous function points to our Redirect, and we get to specify the URL to which we want our user sent.
An Important Note
You will have to import any and all Router elements into whatever file you are intending to use them. For example, to do everything listed in this post, you would need to import the proper items at the top of your file:
import {BrowserRouter as Router, Route, NavLink, Switch, Redirect} from 'react-router-dom';
Thanks for stopping by, and happy routing!
Top comments (8)
I rarely if ever leave comments, but I am leaving one for you, because you are awesome.
You put an incredibly clear answer to the question right at the top of your blog post. Every one should do this. I applaud you. You made my day.
I am so glad it helped!
I too found it so much helpful and informative. Been trying to figure out an easy way for days for passing states and rendering with router. You are awesome.
Hi, now after doing '1. Passing the whole dang state', how do i update the state (of App component in App.js) from Homepage component (launched using BrowserRouter) ?
edited: I have to pass the update functions as another prop just like passing state as prop.
Had to leave a comment. THANK YOU for not making me skim through 5 paragraphs on what react is and the history of javascript. Answer right at the top, keep up the good work!
I signed up for this website just to say this was the most helpful article I have ever read. I love the summary at the top.
Whoah!! This.Was.Awesome.
And what sort of Saint places the solution at the top of the blog? You are wonderful.
That was really awesome, really helped......how about for functional based components though..sorry for asking newbie here!!