Warning: Did not expect server HTML to contain a <li> in <ul>. in React/Redux Server side Rendering
The problem was that since the server had rendered the list of users already, it had a ul
with li
s. But when the client loaded there was no initial data so there was only an ul
and no li
s to accompany it.
To fix this problem, which I think not many will have because you need to do this anyway in server side rendering is to pass some initial state into the createStore
redux function:
You will need to do this in two places. In the html on your server side and in your entry point on the client side.
Short example could be:
<html>
<head></head>
<body>
<div id="root">${content}</div>
<script>
window.INITIAL_STATE = ${serialize(store.getState())}
</script>
<script src="bundle.js"></script>
</body>
</html>
As you can see we have to set the initial state to the store that you created on your server side.
On your client side:
// Startup point for the client side application
import 'babel-polyfill';
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import { Provider } from 'react-redux';
import { renderRoutes } from 'react-router-config';
import Routes from './Routes';
import reducers from './reducers';
const store = createStore(reducers, window.INITIAL_STATE, applyMiddleware(thunk));
ReactDOM.hydrate(
<Provider store={store}>
<BrowserRouter>
<div>{renderRoutes(Routes)}</div>
</BrowserRouter>
</Provider>,
document.querySelector('#root')
);
Now you have access to this global variable window.INITIAL_STATE
and you just pass that through into the second argument of createStore
which is the initial state.