Search code examples
reactjsreact-domreact-dom-server

Will ReactDOM.hydrate() trigger lifecycle methods on the client?


From the React 16 docs about ReactDOM.hydrate(),

Same as render(), but is used to hydrate a container whose HTML contents were rendered by ReactDOMServer. React will attempt to attach event listeners to the existing markup.

  1. Will ReactDOM.hydrate() also trigger lifecycle methods on the client such as componentWillMount(), componentDidMount() during initial render?

  2. Will render() method be called on the client during hydration? I suppose not, because that's the difference between ReactDOM.render() and ReactDOM.hydrate()?

If render method won't be called on the client, we wouldn't expect componentDidMount() lifecycle method to be triggered.

If none of the lifecycle methods are called on the client, how would we know when has React finished rendering. I suppose the callback in the following syntax:

ReactDOM.hydrate(element, container[, callback])

I want to understand if there are lifecycle methods / hooks (which give more control over the application) available when React is "attempting to attach event listeners to existing markup".


Solution

    1. Since ReactDOM.hydrate is (and should be) called on the client then YES it is supposed to run componentDidMount. componentWillMount is already called when rendered on the server. componentDidMount does not run on the server, therefore when you call hydrate, the app runs the event.

    2. Think about hydrate as a different render method. It does render but not in the same way. It looks for mismatches between your server rendered React and your client React. It does not render everything again.

    React expects that the rendered content is identical between the server and the client. It can patch up differences in text content (such as timestamps), but you should treat mismatches as bugs and fix them

    However you might want to do some crazy stuff like rendering something completely different on the client side (than what was rendered on the server). For this pay attention to this paragraph

    If you intentionally need to render something different on the server and the client, you can do a two-pass rendering. Components that render something different on the client can read a state variable like this.state.isClient, which you can set to true in componentDidMount(). This way the initial render pass will render the same content as the server, avoiding mismatches, but an additional pass will happen synchronously right after hydration. Note that this approach will make your components slower because they have to render twice, so use it with caution.

    So as you can see it does a render pass. If there are no mismatches React is optimized for that.

    I hope it was clarifying. I speak from experience with React SSR and basic understanding of reading the docs.