4.3 Add a Router
The next piece of the puzzle is to add a router to interpret browser URLs. We’ll use the
react-router package for this. We’ll also use the
react-router-redux package: this will allow us to connect the router with redux, and change the state through the route.
1.Introduction2 lessons, 04:39
2.Get Started With Redux6 lessons, 41:43
3.Create React Components8 lessons, 50:18
4.Application Structure9 lessons, 56:09
5.Implement the App9 lessons, 1:31:34
6.Conclusion1 lesson, 01:32
4.3 Add a Router
So far we haven't managed a whole lot of UI state but the UI state that we have managed which is showing in hiding our ADD deck input box has been managed through our redux store. Now for some things like our adding deck property that makes perfect sense. However for a more complete application, we're gonna wanna have different routes that show different views and of course switching between those views is a UI change. So what we could do is add other UI state properties. For example, to show a certain deck, we have the showing deck property. For showing the new card modal, we have the show new card modal property. For showing study mode, we have a study mode property, and we could have all these different UI properties. However each one of these different views would make more sense as their own wrote. And so we can actually manage the state through the route. This is of course not going to be any more difficult for us in fact it might be a little bit easier and it has the added benefit that a user could bookmark individual decks or even bookmark study mode for an individual deck. So before we add these other features that are gonna require their own routes, let's add a router. Now if you worked with react before you may be familiar with the package react-router. This is a great package that makes routing in react super simple. The other package that we're going to add is maybe predictably called react-router-redux. And this is just some very basic bindings that will tie together redux and the react-router. So let's go ahead and install those. All right. Now back in our app.js file, let's go ahead and do some more importing here. I'm going to import a couple of things from the react-router library. We're going to import the Router component. We're going to import the Route component and we're also going to import the browserHistory object. We could use different types of history. For example, push date history versus hash history. We're gonna use push date or browser history. So let's import that history object so that we can use that. Also we need to import a few things from react-router-redux. Now in here we have two things that we need. First is a function called syncHistoryWithStore. And as you can imagine what this will do is tie the browser history or the current URL state to our redox store. So let's import syncHistoryWithStore and then we also want to import the routerReducer. And we're gonna add this to our list of reducers that our store uses. Let's actually start with that because it's gonna be the simplest. What we could do is right underneath where we're importing our reducers here we could say reducers.routing = routerReducer. And so remember that when we import star as reducers we have an object with all of our reducers as its properties and so we're just adding a new property called routing and routerReducer is gonna be that reducer function. So now of course this is going to be added when we do combine reducers and create our store. So now we're using that router successfully. Now there is one more variable actually we'll make it a constant, that we need to create before we can actually use the router, and that is the history object. Now you might remember we just said that we're gonna use this browserHistory object, right? And we will but we wanna combine this browserHistory object with reduxKnowledge, right? And that's what we use the SyncHistoryWithStoreFunction for. So we can call SyncHistoryWithStore. We're gonna pass at the history object that we would like to use, which is browserHistory and then of course we pass at the store that we want to sync with. So, whenever the browser history changes this will be synced with the store and of course we'll use our new history object instead of just the raw browserHistory object. So, now we can actually use our router in the way we use the router is actually with JSX. It provides us with these components router and route and we can create a structure of routes here when we're rendering our application. So, this is gonna go right inside the provider. Remember, this provider from react-redux gives everything access to our store. So, just inside that, let's create a Router object, and we'll have opening and closing tags for this. Now, this Router object is going to need a history property, and so let's pass it that history object that we just created. So now within our Router here we can create individual routes. And these routes will tell the router what component to render based on a given URL. So for example we can say if the path is the home route so just a forward slash then the component that we want to render is the App component. Now, this is actually exactly what we wanna do and so we're gonna have to take out where we're rendering our app here. However, if we do that we're not gonna get our sidebar, right? In fact I can show you if we just delete that and now we come back to the browser, you can see that we don't have any errors but we don't have any content either. Which means we're using the router but we're not rendering our sidebar. So, let's open up our App component. And, let's see what do we need for a sidebar. Well thanks to react-redux and the provider that we're using. All we need is this sidebar. It makes our components very easy to move around because we don't have to pull around a whole bunch of actions and other functions with it. We can just import our sidebar and remember because now we're inside the components folder I can take that part out of our import url here so we're just importing sidebar. And let's add it to our app. All right, let's make sure everything's saved. And if we come back to our code here you can see that now we have our sidebar. And of course everything will still be working. Now there is something you might notice, we just got a couple of errors down here in the console. We have the error [react-router] You cannot change ; will be ignored. I've done a lot of research to figure out why I'm getting this error, and I'm pretty sure it's a bug, and one simple reason why I can show you it's a bug. If we do not define our router inside of our run function, but instead, defined it outside. For example, constant routes, let's grab this root route here and paste it in here so that we have a variable that defines these routes. And then inside the router here we can just use the JSX syntax because this is all JSX and just put our routes in there. If we do this and the page of course refreshes when I click New Deck, I add a deck notice that now I can go through the workflow and we don't actually have any errors. I tried to dig into the reactor source and see what was going on but seems like for some reason react-router thinks we're changing these routes in some way when they're actually written in here. Anyway I'm sure this bug will be fixed in no time. However if you don't want the error you can just do this, you can write your routes outside of this and all the other routes that we create from now on are actually gonna go inside of this one route that we've created. So they'll all fit very nicely inside this variable, very easy to do and then you just bring it in with the curly brace syntax of JSX. However I am going to ignore those errors and I'm just gonna leave the route in here for now. So you can do whichever makes you more comfortable. So that's it for this lesson. We are now using the react-router and react router redux packages to make it easy for us to control the URL in the browser while just playing certain components. Now at this point we only have our single route. So we haven't really seen the router in use too much but now that we have this router in place we can start creating components that might go under different specific threads. So in the next lesson we're going to start talking about displaying individual decks.