dev

For Future Generations – ReactJS: “You’re trying to render a component to…”

Introduction

ReactJS is a popular framework these days. It bring a lot of new feature and ideas into frontend development. But is has a very big “problem” or “disadvantage”. Because it is very new, it has a lot of new releases that bring problems with compatibility, obsolete documentation and tutorials.

One of Many Examples

constructor(props) {
    super(props);

    const show = Storage.get("showCookieBar";);
    this.state = {
        showBar: show == null ? true : show
    };
}

render() {
    return (<CookieBar showBar={this.state.showBar} />);
}

What is bad with this code? These lines:

this.state = {
    showBar: show == null ? true : show
};

It raises following exception:

bundle.js:1 Uncaught Invariant Violation: You’re trying to render a component to the document using server rendering but the checksum was invalid. This usually means you rendered a different component type or props on the client from the one on the server, or your render() methods are impure. React cannot handle this case due to cross-browser quirks by rendering at the document root. You should look for environment dependent code in your components and ensure the props are the same client and server side:
 (client) <html data-reactid=
 (server) <html data-reactid=

Ok, ReactJS gives you a long description what is wrong, but the code is very simple.

The problem is that you cannot evaluate condition and set it into state in constructor. Because the evaluation differs on server and client.

The correct way is to move evaluation into componentDidMount method:

constructor(props) {
    super(props);

    this.state = {
        showBar: false
    };
}

componentDidMount() {
    const show = Storage.get("showCookieBar");
    this.setState({
        showBar: show == null ? true : show
    });
}

render() {
    return (<CookieBar showBar={this.state.showBar} />);
}

And now, everything works as expected. I hope that it will helps to somebody else, because I haven’t found a solution of similar posts on the internet.