Add Redux with Server-to-Client State Hydration to a React Universal Project

Tim Kindberg
InstructorTim Kindberg
Share this video with your friends

Social Share Links

Send Tweet

We will add redux to our project and get redux working on the client and server. The redux state will be passed along with our server-side rendered page in a global window variable; from there, we’ll hydrate the state on the client.

Instructor: [00:00] I've added Redux to my project. I'm no longer controlling the selected state internally to the component. I'm actually using two props that I'm getting from Redux, selected, and select tab, to control the selected state and set the selected state. Select tab is an action that I have. Get selected tab is a selector that pulls the selected tab off the state.

[00:26] At the bottom, I am mapping in the selected tab to the prop called selected. I'm mapping in select tab to a prop called select tab. I'd like to be able to click on each tab and change the state in Redux. Let's see how we can make Redux work with React universal component.

[00:48] Let's set up our provider in the index. I need to import the provider. I'm going to import a function called configure store from a file that I've not written yet. The configure store file will just be an isolated place that we can set up the Redux store. It's going to return a store. It's going to accept an initial state.

[01:17] When you render on the server, you're already rendering your app, but really your app is nothing without your state. You want to make sure you're rendering your app with the proper Redux state already baked in. That will just work.

[01:31] However, if you don't pre-populate your store on the client, then it has to do that work all over again when it loads on the client. It's best to just sort of tell Redux, "Here's the state. I've already figured it out."

[01:43] The simplest place to store that is just on a private property on window. We're just going to add the state to this private window property called initial state. Now let's use our provider. We'll set the store on the provider to the store that we created.

[02:08] We need to create a new file called configure store. We want to import create store from Redux. We want to import our reducer from reducer/index. We're going to go ahead and create our method here called configure store.

[02:36] Remember, we're going to be taking in the initial state. That's coming off the window. That's the window initial state. Here we want to just use the actual create store from Redux, pass it our reducer and our initial state. We're going to return the store. I just want to export this as the default.

[03:05] Another neat thing you can do here is actually set up hot module reloading for your reducers. If module.hot exists, then we want to module hot accept any changes to the reducers.

[03:22] If those change, we're going to go ahead and just use the store.replace reducer. We're going to import a fresh copy of the reducers and put those into the store and replace the old ones.

[03:41] Now, we need to pre-populate the state on the window. We're going to have to go to the server's render JS file to do that. We need to import the provider from React Redux just like we do one the front end. We're also going to need that configure store function that we just wrote.

[04:09] Let's go ahead and create the store. This time, we're not going to give it an initial state because this is the first time we're actually rendering it on the server. Let's figure out what our initial state is by stringifying the store's current state. We need to wrap our app in the provider and then give the provider access to the store.

[04:46] Now we go down to our HTML response. We're going to add a script tag. Here's where we're going to add that initial state.

[05:05] Let's see if everything worked. We have a syntax error. That's going to be easy to fix, just have to move my comma. Refresh. Bar is loaded. Let's check out what was sent down from the server. If we look at local host, open in the sources panel, we see window initial state is set to our Redux state.

[05:34] That's going to be populated straight into the Redux state on the client side. Then we're seeing the state of our app was also reading from our initial state where bar is loaded. That was all coming from our tabs reducer where a selected tab started as bar.

[05:54] If I were to change this to home and refresh, we're seeing home is loaded, the initial state is coming down as home, and the initial server side renderer of our app is also home is loaded.