Can cause hydration mismatch with SSR
See original GitHub issueFirst off, really nice hook! One issue I’m seeing for SSR’ed apps is if the stored value affects DOM structure then there’s going to be a hydration mismatch warning (for example Warning: Expected server HTML to contain a matching <div> in <div>
).
One workaround:
export default function Todos() {
const [query, setQuery] = useState('')
const [todos, setTodos] = useLocalStorageState('todos', ['buy milk'])
// Keep track of whether app has mounted (hydration is done)
const [hasMounted, setHasMounted] = useState(false);
useEffect(() => {
setHasMounted(true)
}, []);
function onClick() {
setTodos([...todos, query])
}
return (
<>
<input value={query} onChange={e => setQuery(e.target.value)} />
<button onClick={onClick}>Create</button>
{/* Only render todos after mount */}
{hasMounted && todos.map(todo => (<div>{todo}</div>))}
</>
)
}
Maybe we can include a section in the readme that covers this? I’m not sure if there’s an elegant way for the to hook to handle this. It could wait until mount to return the value from storage, but then that means an extra re-render for non-SSR apps. Thoughts?
More discussion: https://twitter.com/gabe_ragland/status/1232055916033273858 https://www.joshwcomeau.com/react/the-perils-of-rehydration/
Issue Analytics
- State:
- Created 3 years ago
- Reactions:4
- Comments:23 (13 by maintainers)
Top Results From Across the Web
Hydration Mismatch - vite-plugin-ssr
Hydration mismatches can induce performance degradation and bugs and should be avoided. Example. Let's imagine we render the current date's milliseconds: <span> ...
Read more >Handling the React server hydration mismatch error
There's no hydration from server rendering happening, so there's no need for the initial render to use the default values.
Read more >Easily Fix React Hydration Errors - Travis Wimer
Hydration failed because the initial UI does not match what was rendered on the server. There was an error while hydrating. Because the...
Read more >Debugging and fixing hydration issues - somewhat abstract
It is almost working beautifully, but when we tried to hydrate our SSR (server-side rendered) result, we hit a snag; our SSR result...
Read more >Understand and solve hydration errors in Vue.js - sum.cumo
and turns it into dynamic DOM that can react to client-side data changes. When the browser calls up a URL, the browser is...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
I really like the idea for
useSsrMismatch
and could see myself using it in custom hooks I write and when dealing with libraries that don’t handle this. It seems like a much better solution than how I useuseHasHydrated
in my above example.I think my preference would still be to have this integrated into the library and have it be opt-out like Material UI’s
useMediaQuery
hook.So maybe the API would look like:
The logic being that Next.js and Gatsby are growing in popularity and it’s better that a non-SSR user have an unnecessary re-render than having SSR users run into subtle bugs or have to understand how to use
useSsrMismatch
. I’m assuming the performance cost ofuseLayoutEffect
is pretty small, but probably worth looking into first.The current state is — I like the idea and I am willing to implement it. I will post here when I start working on it.