I am trying to pass in data during server side rendering for a simple app.
I have this data provider both in the server and client and I use a global variable to inject the initial state into the client:
import React, { Component } from 'react';
export default class SsrDataProvider extends Component {
constructor(props) {
super(props);
this.state = { data: window.__INITIAL_STATE__ };
}
getChildContext() {
return { data: this.state.data };
}
render() {
return this.props.children;
}
}
SsrDataProvider.propTypes = {
children: React.PropTypes.object,
};
SsrDataProvider.childContextTypes = {
data: React.PropTypes.object,
};
In the server, window.INITIAL_STATE gets replaced with the actual data passed in through a prop:
renderToString(<SsrDataProvider {...renderProps} data={data} />)
and the data provider renders the router context instead of children...
render() {
return <RouterContext {...this.props} />;
}
The problem is that the context isn't defined during server rendering. It's like it was never passed in at all. Then when the javascript bundle arrives to the client it uses the window.INITIAL_STATE variable and picks up where the server left off. It works, but I might as well not do any server side rendering. Is there something I'm missing? or maybe renderToString() does not support context?
You should be setting the initial state based off of
props.data
if it is defined.Really though, you shouldn't even be including
window.__INITIAL_STATE__
inside of the component. Instead, you should also be passing in thedata
prop wherever it is that you're rendering the<SsrDataProvider>
on the client side.