Issue 1:
Do you want to request a feature or report a bug?

Feature

What is the current behavior?

Hydrating some server-rendered content can be difficult, inefficient or impossible. For example, in the process of rendering on the server, significant work or additional data may be required for data processing and conversion, such as custom templating or localization. The content can be large too, such as product information or a news article.

When the resulting content is highly dynamic and changes with state, there is no choice but recreate it within React paradigm and recreate it on client. However, complicated server-generated content is often (if not typically) static. Delivering a redundant copy of static content to client just to compare and ignore it during hydration seems a waste of resources and can be prohibitively expensive.

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem. Your bug will get fixed much faster if we can run your code and it doesn't have dependencies other than React. Paste the link to your JSFiddle (https://jsfiddle.net/Luktwrdm/) or CodeSandbox (https://codesandbox.io/s/new) example below:

https://codesandbox.io/s/zx38ow3z8x

What is the expected behavior?

Instead of additional complications of recreating it on the client with hydration, wouldn’t it be much easier to just accept the content from server as-is and tell hydrate() to leave it alone?

There may be a few options for non-hydrating SSR:

Add a new callback shouldComponentHydrate() to disable hydration of component content

export default class NoHydrate extends Component {
// return false to avoid re-rendering of this component in hydrate()
shouldComponentHydrate() {
return false;
}
render() {
// on server, simply render content
// on client, this is never called and server content is accepted as-is
return (
<div>
{this.props.children}
</div>
);
}
}

Access SSR content from DOM in render()

This is probably the worst option, though it is the only one that definitely works currently.

export default class AutoHydrate extends Component {
render() {
// on server, simply render content
// on client, find SSR in dom and re-render using dangerouslySetInnerHTML
// ** requires a unique id, generated before or during server rendering **
return (typeof window === 'undefined') ? (
<div id={this.props.id}>
{this.props.children}
</div
) : (
<div id={this.props.id}
dangerouslySetInnerHTML={{
__html: document.getElementById(this.props.id).innerHTML
}}
/>
);
}
}

Use dangerouslySetInnerHTML with empty content

It actually works now, but it is not documented that it is supposed to.

export default class Ssr extends Component {
render() {
// on server, simply render content
// on client, render empty content using dangerouslySetInnerHTML,
// which normally causes a warning of content mismatch and keeps the existing content
// also add suppressHydrationWarning to turn off the warning.
return (typeof window === 'undefined') ? (
<div>
{this.props.children}
</div>
) : (
<div
dangerouslySetInnerHTML={{
__html: ''
}}
suppressHydrationWarning
/>
);
}
}

Considering that there is a way to make it work now, documenting (3) may be all that needs to happen. However if (1) could be added with same behavior, it would look cleaner.

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?

Version 16.2. Not sure if the working option 3 has worked before or is supposed to work in future versions.

Issue 2:
The New York Times is rebuilding its website using React. Currently, it’s an isomorphic app that has both server- and client-side renders.

Our question: What's the best way to include a non-React interactive graphic — maps, charts and other visualizations created by custom code — within a fully React page?

Our ideal scenario:

Server-side React renders the initial HTML for a graphic, using dangerouslySetInnerHTML, as part of a React page

Client-side React never touches those elements again, even during component mounting

We thought React 16 might solve this with hydrate method, but it still removes nodes that it doesn't expect, such as nodes generated by D3 or other client-side code. None of the options in Integrating with Other Libraries seem to be an exact match either.

The classic use case is a graphic with a D3 map. The server-side HTML includes text and a placeholder

for the map, as well as the map JS. On page load, the map is immediately drawn by D3 but gets erased when React mounts client-side. The D3 nodes aren’t included in the server-side output, because they often vary based on viewport, device, etc.

Here’s a trivial example, showing React 16’s hydrate removing client-created nodes after one second. On mobile devices, loading the React library and potentially other dependencies could take some seconds.

The simplest solution I can think of is a shouldComponentMount function, where we could return false. The rest of the React components on the page would mount, but leave the interactive graphic part alone. There are probably other solutions.

Constraints:

We need to use dangerouslySetInnerHTML, because we need to deploy graphics outside of site releases

We need to render the initial HTML server-side for performance and simplicity

We can’t use iFrames for everything, as they’re not flexible enough

We can’t re-render or reattach elements, as that causes many problems — CSS animations restart, media playback is interrupted, input cursors and text selections are lost, etc.

Any guidance is appreciated.

cc @gaearon @leeb