Skip to content

Instantly share code, notes, and snippets.

@esamattis
Created June 5, 2022 14:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save esamattis/99a3d95e6445f5ecb360683867710acd to your computer and use it in GitHub Desktop.
Save esamattis/99a3d95e6445f5ecb360683867710acd to your computer and use it in GitHub Desktop.
Prevent React hydration on specific element (HACK)
/**
* Render a div which preserves its server-side content on browser hydration.
*/
function NoHydrate(props: { id?: string; children: React.ReactNode }) {
const id = props.id ?? "no-hydrate";
const container = useRef<HTMLDivElement>(null);
const save = useRef<Node[]>();
// During the first render capture clones of the children. Reading the DOM
// during React render is a hack but the only way to access the DOM before
// React destroys it.
if (typeof window !== "undefined" && !save.current) {
const style = document.getElementById(id);
if (style && !save.current) {
save.current = Array.from(style.childNodes).map((child) =>
child.cloneNode(true),
);
}
}
// After the React render React has potentially destoyed the children so we
// restore them
useLayoutEffect(() => {
if (save.current) {
for (const node of save.current) {
container.current?.appendChild(node);
}
}
}, []);
return useMemo(
() => (
<div id={id} ref={container} suppressHydrationWarning>
{props.children}
</div>
),
[id],
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment