Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React/Redux server side rendering initial state

I have a React/Redux application that keeps track of a user's authenticated state in local storage. The application is also set up to use server side rendering. I'm running into issues when rendering the initial application state. My server creates a new store and emits the SET_INITIAL_STATE action. This initial action on the client side reads localStorage and passes the authenticated information on to my reducers. The server, however, has no knowledge of this logged in state since I'm using stateless JWT located in local storage for authentication.

Since the server and client are out of sync at this point, I'm getting this error:

React attempted to reuse markup in a container but the checksum was invalid. This generally means that you are using server rendering and the markup generated on the server was not what the client was expecting. React injected new markup to compensate which works but you have lost many of the benefits of server rendering. Instead, figure out why the markup being generated is different on the client or server:

Which makes sense, because the server is trying to render an unauthenticated state.

What is the accepted standard or practice for setting this initial state that relies solely on something the client has access to?

like image 980
ThinkingInBits Avatar asked Dec 29 '15 21:12

ThinkingInBits


People also ask

Can we use Redux in server-side rendering?

Redux on the Server​When using Redux with server rendering, we must also send the state of our app along in our response, so the client can use it as the initial state. This is important because, if we preload any data before generating the HTML, we want the client to also have access to this data.

How do I change the initial state in Redux from API?

How to define initialState from API? import * as types from '../constants/ActionTypes' import { combineReducers } from 'redux' import Immutable from 'immutable' const initialState = { initialLentItems: [], lentItems: [] } function initialLentItems(state = initialState.

Can you React to server-side rendering?

Yes! This is where server-side rendering for React comes in. In this article, I want to introduce you to server-side rending (SSR) with React, reasons to use it, and some popular frameworks for rendering React on the server side.

Is React server-side rendering or client-side?

By default, your React app will be client-side rendered. This means basically, all of the source code will live in JavaScript files referenced in a single HTML file that initializes your app.


Video Answer


2 Answers

I found that the OP is right, that cookie storage is the best option. If you're using react, redux, and express for a universal app the option that worked for me was https://github.com/eXon/react-cookie.

Essentially:

In you server side code you can use:

  import cookie from 'react-cookie';

  function handleRender(req, res) {
      cookie.setRawCookie(req.headers.cookie);

      // Create new Redux store instance
      const store = createStore(rootReducer, {
          username: cookie.load('username') || '',
          accessLevel: cookie.load('accessLevel') || userRoles.public,
      });

      //other react/redux/express related code
  }

In your react applications, inside the components, you can just save the cookies directly:

  import cookie from 'react-cookie';

  //first parameter is anything you want, second is the data you want to save
  cookie.save( 'username', username );
  cookie.save('accessLevel', accessLevel);

Further if you want to store an object, as I did, you can pass in JSON.stringify(your object). cookie.load will automatically parse it for you.

In my code I called cookie.save from the actions, but you can call it directly in components or any abstraction you have.

like image 84
Boomer Rogers Avatar answered Oct 27 '22 09:10

Boomer Rogers


I found a working solution.

The trick, unfortunately, is to store the authenticated state in a cookie so the session state gets sent to the server automatically upon request.

like image 41
ThinkingInBits Avatar answered Oct 27 '22 10:10

ThinkingInBits