10

I've got code like the following where I'm calling ReactDOM.hydrate. This is shared code that sometimes gets called from the node server and sometimes in the client browser. Do I need to do anything different (then calling hydrate) when calling it on the client only. Normally, I'd call render.

const render = Component => {
 ReactDOM.hydrate(
    <Router history={browserHistory}>
        <FullPage />
    </Router>,
    document.getElementById('root')
 )
}

render(App);

nbkhope
  • 7,360
  • 4
  • 40
  • 58
Peter Kellner
  • 14,748
  • 25
  • 102
  • 188
  • I guess you will find an answer here: https://stackoverflow.com/questions/46516395/whats-the-difference-between-hydrate-and-render-in-react-16 – Pierre Kraemer Jan 15 '18 at 11:42
  • @PierreKraemer , I did read that post and it was not clear to me that hydrate can be used as a replacement in all cases for render. This comment "If you call ReactDOM.hydrate() on a node that already has this server-rendered markup" makes me think maybe yes but it does not say that. – Peter Kellner Jan 15 '18 at 15:26
  • 1
    Yes sorry, I did not get at first that you want to know if hydrate can be used in all cases, even if the component has not been server-side rendered. From the docs, I get that hydrate is dedicated to attach listeners to a server-side rendered markup that should be the exact same result as if it had been client-side rendered with render. I am not sure of what happens if the given container is empty.. – Pierre Kraemer Jan 15 '18 at 15:43

2 Answers2

7

hydrate do works similar to render on client side whether the HTML has server rendered markup or not, but when there is no markup previously like not SSR then hydrate produces some warnings but, it will render your markup as expected. A better way to solve this would be to check if its SSR (assuming root as your parent div id) :

var isMarkupPresent = document.getElementById('root').hasChildNodes();

and then you can either render or hydrate:

isMarkupPresent ? hydrate(...) ? render(...)
Fawaz
  • 3,404
  • 3
  • 17
  • 22
1

Strictly speaking, no it is not safe to always use ReactDOM.hydrate().

From the docs on hydrate, you should only use it on "a container whose HTML contents were rendered by ReactDOMServer". hydrate also expects that the server rendered markup is identical to what the client side render outputs, and any differences should be considered bugs.

ReactDOM.render() on the other hand is used to render your app into an empty container on the client. You may need to do this if you don't have server rendered markup on all pages.

Because render() handles a use case that hydrate() does not, it is not safe to say "you can always use ReactDOM.hydrate()".

Caleb Miller
  • 1,022
  • 9
  • 14