Error: Hydration failed because the initial UI does not match what was rendered on the server
This is a common error when using React with Server Side Rendering (SSR) or any another type of pre-generated HTML.
Fortunately, the fix is fairly simple, and I also published an NPM package that can help make the solution even easier.
As the error suggests, this problem occurs when the HTML from the server does not match what the client-side is trying to render.
This can happen any time you have dynamic text. For example, if you are rendering dates or times, different environment may return different results:
function MyComponent() {
const date = new Date();
return <time>{date}</time>;
}
This code is dependent on the current time. Since the pre-rendered HTML and the client-side app are rendering at different times, the time returned by new Date() will be different.
React "Hydration" only cares that the content matches during the very first render. After that we can change anything we want without issues.
So one option is to simply remove the content from the first render:
export default function MyComponent() {
const [initialRenderComplete, setInitialRenderComplete] = React.useState(false);
// This useEffect will only run once, during the first render
React.useEffect(() => {
// Updating a state causes a re-render
setInitialRenderComplete(true);
}, []);
// initialRenderComplete will be false on the first render and true on all following renders
if (!initialRenderComplete) {
// Returning null will prevent the component from rendering, so the content will simply be missing from
// the server HTML and also wont render during the first client-side render.
return null;
} else {
const date = new Date();
return <time>{date}</time>;
}
}
Of course, you don't have to return null. You can still render something if you'd like, you just need to ensure it does not contain any dynamic values.
This is a simple solution, but there are also potential pitfalls. If you would like to learn more about React Hydration errors, you can read my other blog post: