Skip to content

Instantly share code, notes, and snippets.

@james2doyle
Last active March 25, 2024 22:42
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 james2doyle/6a23ba3db87a9979c5f86bf3472256da to your computer and use it in GitHub Desktop.
Save james2doyle/6a23ba3db87a9979c5f86bf3472256da to your computer and use it in GitHub Desktop.
React.useSyncExternalStore is exactly what we need to avoid hydration errors, and moreover, if we transition to a page with useSyncExternalStore on the client, the clientSnapshot will immediately be taken. Taken from: https://tkdodo.eu/blog/avoiding-hydration-mismatches-with-use-sync-external-store
/**
* ClientGate - a component that will only render on the client, where you can safely access browser only APIs
*
* Usage: `<ClientGate>{() => `Hello Client ${window.title}`}</ClientGate>`
* @see https://tkdodo.eu/blog/avoiding-hydration-mismatches-with-use-sync-external-store#usesyncexternalstore
*/
const emptySubscribe = () => () => {};
const ClientGate = ({ children }: React.PropsWithChildren) => {
const isServer = React.useSyncExternalStore(
emptySubscribe,
() => false,
() => true,
);
return isServer ? null : children();
};
export default ClientGate;
/**
* stable-server-value: we can produce a stable date output on the server, we can limit the content shift to only the date
*
* @see https://tkdodo.eu/blog/avoiding-hydration-mismatches-with-use-sync-external-store#usesyncexternalstore
*/
const emptySubscribe = () => () => {};
const ComponentWithDefaultValue: React.FC<
React.HTMLAttributes<HTMLDivElement>
> = ({ children, ...rest }) => {
const date = React.useSyncExternalStore(
emptySubscribe,
() => /* client call */ lastUpdated.toLocaleDateString(),
() => /* server call */ lastUpdated.toLocaleDateString('en-US'),
);
return (
<div {...rest}>
<span>Last updated at: {date}</span>
{children}
</div>
);
};
export default ComponentWithDefaultValue;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment