Introduction to how redux works with SSR

黃子洋
5 min readAug 25, 2022

Introduction

The motivation for this article is that I want to use redux with NextJS in my next side-project. As you know NextJS is a really powerful react framework to handle either SSG (static site generator) or SSR (server-side rendering), both of these techniques would execute some code in a server before rendering the HTML to the client.

Previously, I always use redux in a CSR (client-side rendering) web app, and now when I want to dispatch some actions inside the function in the getStaticProps or getServerSideProps function in NextJS, We would have to set up additional stuff to deal with it, which makes me want to see how it actually works when using redux with SSR.

The Purpose of SSR

I will simply go through some points of the advantages which SSR provides

Better SEO

SSR will return authenticate HTML template from a server when the client visits our website, unlike the modern SPA framework which will only show the tag of <div id="App"></div> , showing the full HTML of the page will help browser crawlers to get more insight into the website and improve the SEO.

UI might appears faster

In a CSR application, the view of the web page will be visible after the javascript file is loaded, while in an SSR application, the HTML template will first appear(with no interactivity) and the javascript will start loading to give our web page interactivity. So in most cases, the web page will be visible to the user faster in an SSR application than in a CSR application.

and I think there are more advantages and caveats explained on the web

Redux on the server

As we know, the most common usage of SSR is to handle the initial render of a user requesting our web page, and here are the steps.

  1. The client requests our web page
  2. The server receives the request and tries to transform the required components into a string
  3. The server sends back the HTML string with a javascript file instead of a single bundle.js file back to the client.

The server also has to deal with the initial state we want and send it back with the HTML string from the server and here is how we handle redux on the server.

According to the Redux documentation, here’s what we need to do

  • create a fresh, new Redux store instance on every request;
  • optionally dispatch some actions;
  • pull the state out of the store;
  • and then pass the state along to the client.

And on the client side, we will initiate the store with the state passed back from the server.

Redux’s only job on the server side is to provide the initial state of our app.

Let’s walk through some code

First, we will set up an express server, whenever the client makes a request to our web page, the handleRender middleware function will be executed.

from redux official doc https://redux.js.org/usage/server-rendering

Next, here is the implementation of the handleRender middleware function and renderFullPage function. The handleRender middleware function simply does three things.

  1. create a redux store
  2. fetch the initial state of the application
  3. call the renderToString method to get the HTML string returned to the client

In the renderToString function we stored the preloaded state inside a global variable named window.__PRELOADED_STATE__

After all these steps, we are back to our client side.

On the client side, we first initialize our store using the pre-defined state in the window.__PRELOADED_STATE__ and hydrate the HTML string which the server responds to us.

That’s what it is stated in the redux official doc of how to do SSR with redux.

Preparing the initialState by request parameters

When we use libraries like react-router we want to mutate the state differently by the URL or request parameters, how should we do it?

By parsing the req parameter exposed by express, we can return different initial state to the client side by different routes and request parameters.

Async state fetching

When we want to mutate the state according to some asynchronous request, like fetching data from our database. here is how we do it.

Create a method that accepts a callback

We first create a method that accepts a callback function after 500 mili-seconds to simulate an HTTP-request

In the server, we execute this function and input the callback to return our state according to the result of the asynchronous request.

We could do a lot of customization here, for example, match each requested routes by a Router object to execute the API calls for each routes.

Using Redux in NextJS

In NextJS, using the library next-redux-wrapper is a common way for you to deal with redux in the server-side

the process of using redux in server-side functions like getStaticProps and getServerSideProps is similar to the above steps but with a little tweak, here are the rough steps.

  1. Create the store on the server-side
  2. Dispatch the desired actions
  3. The server-side returns the latest piece of state
  4. In the client side, when you navigate to a page, a HYDRATE action is dispatched with the latest piece of state, you have to update the store according to your need.

If you want to know the details, their Github has explicit documentation.

Conclusion

To conclude, similar to the client side, when we want to dispatch an action in our server, we need to have all the required elements (store, reducers) in order for us to produce the correct state and return back to the client side.

Reference

--

--