From 9e86b75b3139565d79e31dc1b7596843c3b91332 Mon Sep 17 00:00:00 2001 From: Joe Duchnowski Date: Fri, 23 Feb 2018 10:46:18 -0500 Subject: [PATCH] Use ReactDOM.hydrate() for hydrating a SSR component if available --- CHANGELOG.md | 2 ++ node_package/src/clientStartup.js | 10 ++++++++-- node_package/src/createReactElement.js | 4 ++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a82659ca4..f85567029 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ Contributors: please follow the recommendations outlined at [keepachangelog.com] Changes since last non-beta release. *Please add entries here for your pull requests that are not yet released.* +#### Fixed +- Use ReactDOM.hydrate() for hydrating a SSR component if available. ReactDOM.render() has been deprecated for use on SSR components in React 16 and this addresses the warning. [PR 1028](https://github.com/shakacode/react_on_rails/pull/1028) by [theJoeBiz](https://github.com/theJoeBiz). ### [10.1.1] - 2018-01-26 #### Fixed diff --git a/node_package/src/clientStartup.js b/node_package/src/clientStartup.js index 2061d8fda..d1b096c43 100644 --- a/node_package/src/clientStartup.js +++ b/node_package/src/clientStartup.js @@ -95,8 +95,8 @@ function domNodeIdForEl(el) { } /** - * Used for client rendering by ReactOnRails. Either calls ReactDOM.render or delegates - * to a renderer registered by the user. + * Used for client rendering by ReactOnRails. Either calls ReactDOM.hydrate, ReactDOM.render, or + * delegates to a renderer registered by the user. * @param el */ function render(el, railsContext) { @@ -115,18 +115,24 @@ function render(el, railsContext) { return; } + // Hydrate if available and was server rendered + const shouldHydrate = !!ReactDOM.hydrate && !!domNode.innerHTML; + const reactElementOrRouterResult = createReactElement({ componentObj, props, domNodeId, trace, railsContext, + shouldHydrate, }); if (isRouterResult(reactElementOrRouterResult)) { throw new Error(`\ You returned a server side type of react-router error: ${JSON.stringify(reactElementOrRouterResult)} You should return a React.Component always for the client side entry point.`); + } else if (shouldHydrate) { + ReactDOM.hydrate(reactElementOrRouterResult, domNode); } else { ReactDOM.render(reactElementOrRouterResult, domNode); } diff --git a/node_package/src/createReactElement.js b/node_package/src/createReactElement.js index 05ad3906f..aa9676fa3 100644 --- a/node_package/src/createReactElement.js +++ b/node_package/src/createReactElement.js @@ -19,6 +19,7 @@ export default function createReactElement({ railsContext, domNodeId, trace, + shouldHydrate, }) { const { name, component, generatorFunction } = componentObj; @@ -26,6 +27,9 @@ export default function createReactElement({ if (railsContext && railsContext.serverSide) { console.log(`RENDERED ${name} to dom node with id: ${domNodeId} with railsContext:`, railsContext); + } else if (shouldHydrate) { + console.log(`HYDRATED ${name} in dom node with id: ${domNodeId} using props, railsContext:`, + props, railsContext); } else { console.log(`RENDERED ${name} to dom node with id: ${domNodeId} with props, railsContext:`, props, railsContext);