I'm trying server-side rendering for the first time in my React/Redux app. An issue I'm having right now is that I need the initial state to have a randomly generated string and then pass it as a prop to my main App
component. This is obviously causing an issue because it's generating different strings for the client and server. Is there something I can do to stop this issue from happening?
Basic structure to help with understanding:
App.js
import React from 'react';
import { connect } from 'react-redux';
const App = ({ randomStr }) => (
<div>
<p>{randomStr}</p>
</div>
);
const mapStateToProps = (state) => ({
...
});
const mapDispatchToProp = (dispatch) => ({
...
});
export default connect(
mapStateToProps,
mapDispatchToProps
)(App);
And my reducer:
reducer.js
import { generateString } from '../util';
import { NEW_STRING } from '../constants';
const stringReducer = (state = generateString(), action) => {
switch (action.type) {
case NEW_STRING:
return generateString();
default:
return state;
}
};
export default stringReducer;
As you can see, I'm getting the randomStr
from my redux store and rendering it, but it is different in client and server. Any help would be appreciated!
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.
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.
When you're generating the store and your initial state on the server side, the client should not do the same and try to regenerate the data.
You need to generate your store and your initial state only once (on the server) and pass it down to the client. To do that, you need to inject it in the initial component you'll be rendering.
The most common approach is to add a <script>
tag and attach the state to your window, for instance in window.__initialState
.
For example, if you're using ReactDOM.renderToString
on the server side to render your initial component called Html
, you can:
const html = ReactDOM.renderToString(<Html initialState={initialState} />);
Then, in your Html
component, you can inject this data so the client can use it later:
<script dangerouslySetInnerHTML={{ __html: `window.__initialState=${JSON.stringify(this.props.initialState)};` }}/>
After that, on the client side, you can use window.__initialState
to get your data back and you'll end up with the same data on the server and the client.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With