-
Notifications
You must be signed in to change notification settings - Fork 50.2k
Description
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
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.