React Context undefined in Server Side Render

2.3k views Asked by At

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?

1

There are 1 answers

1
Paul S On BEST ANSWER

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 the data prop wherever it is that you're rendering the <SsrDataProvider> on the client side.

export default class SsrDataProvider extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      data: props.data // || window.__INITIAL_STATE__
    }
  }
}