New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support partial hydration for static content #12617
Comments
I think this should probably go to https://github.com/reactjs/rfcs |
I'll close as duplicate of #10923. There's a hacky solution in #10923 (comment) (same as you described). |
I think reopening this issue could valuable since targeted hydration is an exciting approach to client performance. Depending on the use case, it can mean shipping a smaller bundle and removing the need for hydration in many cases. I made a proof of concept at https://github.com/kirkstrobeck/hydrator |
I'm using: <StaticContent><MyComponent /></StaticContent> import { createElement, useRef, useState, useEffect } from 'react'
function useStaticContent() {
const ref = useRef(null)
const [render, setRender] = useState(typeof window === 'undefined')
useEffect(() => {
// check if the innerHTML is empty as client side navigation
// need to render the component without server-side backup
const isEmpty = ref.current.innerHTML === ''
if (isEmpty) {
setRender(true)
}
}, [])
return [render, ref]
}
export default function StaticContent({ children, element = 'div', ...props }) {
const [render, ref] = useStaticContent()
// if we're in the server or a spa navigation, just render it
if (render) {
return createElement(element, {
...props,
children,
})
}
// avoid re-render on the client
return createElement(element, {
...props,
ref,
suppressHydrationWarning: true,
dangerouslySetInnerHTML: { __html: '' },
})
} |
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:
shouldComponentHydrate()
to disable hydration of component contentrender()
This is probably the worst option, though it is the only one that definitely works currently.
dangerouslySetInnerHTML
with empty contentIt actually works now, but it is not documented that it is supposed to.
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.
The text was updated successfully, but these errors were encountered: