Universal rendering with React and Redux

How to set up a universal React web application with Redux.

Prerequisite

Redux

Redux is a library that helps manage your state using Flux-like principles. Install it and its official React bindings:

$ npm install redux react-redux

Server

Let’s add Redux on the server-side.

At the top of routes/index.jsx, import Redux and Provider:

routes/index.jsx

Then create a reducer that doesn’t do anything except return the default state that it’s provided:

routes/index.jsx

Now create the store with the props as the initial state:

routes/index.jsx

Finally, update the top-level component to Provider:

routes/index.jsx

You’ll notice that RouterContext's createElement prop is removed. That’s because Redux now manages the state so it’s no longer necessary to merge the props in RouterContext.

routes/index.jsx should now look like this:

routes/index.jsx

Client

To maintain isomorphism, update client.js similarly:

client.js

The only difference is that the store’s initial state comes from window.PROPS because this file is run in the browser.

Since we’re using JSX in client.js, we must import React and make it available.

The webpack configuration must also be updated so files with .js extension are transpiled by Babel (line 10):

webpack.config.js

Don’t forget to restart webpack in the command-line:

# press Ctrl-C to stop the running process first
$ webpack -w

Open routes/routes.jsx and remove Router's createElement prop. The file should look like the following:

routes/routes.jsx

Connect Component To Store

Let’s connect views/Layout.jsx to the Provider store.

First, import connect at the top of the file:

views/Layout.jsx

Then create a higher-order component (HOC) that maps the store’s state to the connected component’s props:

views/Layout.jsx

As you can see here, the store state from Provider is mapped to Layout’s props.custom with the help of React context.

Assign the existing component to the variable Layout and pass it in the wrapper to create the connected component:

views/Layout.jsx

views/Layout.jsx should look something like this:

views/Layout.jsx

When you switch the browser and refresh, you should see that everything still looks and works the same.

If you have React Developer Tools installed, you can confirm that the data is being passed from Connect to Layout.


So going forward, you may want to set up actual actions and reducers for your store. Feel free to check out the code for this tutorial as well as other videos in my React playlist.