- Instant help with your JavaScript coding problems

Fix the React 18: Hydration failed because the initial UI does not match error

Although server side rendering is already available in React 16.8, Automatic hydration will be introduced in React 18. This is the reason why in new React, Next.js projects often show the following error message on the console:

Uncaught Error: Hydration failed because the initial UI does not match what was rendered on the server.
   ...
Warning: An error occurred during hydration. The server HTML was replaced with client content in <#document>.

 

What is hydration

The hydration process is an important part of using server side rendering. Hydration is the process of converting static HTML into a fully interactive React application by attaching event handlers to the DOM elements. This is done when a React application is rendered on the server and then the HTML is sent to the client. When the HTML arrives on the client, React hydrates it by attaching event handlers to the DOM elements so that the user can interact with the application.

The main problem

The error Hydration error occurs when the initial UI rendered on the server does not match the UI rendered on the client after hydration. The most common reasons are:

  • Incorrect HTML. For example a div tag inside a p tag, or a tr outside of tbody
  • Rendering based on client side properties. For example an if statement based on window object.
  • Browser extensions that modify the HTML code. Such as LastPass or Grammarly.

Fix HTML errors

The first step is to check that the HTML code is valid. If you get the error Hydration failed because of an HTML error, you will find validateDOMNesting warnings in the error messages that appear on the console. For example:

Warning: validateDOMNesting(...): <tr> cannot appear as a child of <table>. Add a <tbody>, <thead> or <tfoot> to your code to match the DOM tree generated by the browser.

or

Warning: validateDOMNesting(...): <div> cannot appear as a descendant of <p>.

These mistakes are definitely worth correcting.

Fix Hydration error with useEffect

If you don't need server side rendering, you can work around the error with the useEffect hook. The hook can be used to update the component's state on the client after the component has been hydrated. This will ensure that the component renders the same content server-side and client-side.

For example:

"use client"

import Home from '@/components/Home';
import { useEffect, useState } from 'react';

export default function HomePage() {

  const [firstRender, setFirstRender] = useState(true);

  useEffect(()=>{
    setFirstRender(false);
  },[]);

  if (firstRender) {
    return <></>
  }

  return <Home />
}

The first line is important for Next.js. Since useEffect is only used for client components and by default all components are server components in Next.js, you need to specifically mark that this is a client component using the "use client" .

Fix by disabling SSR

For Next.js projects, you can also use dynamic import, where you explicitly define that the component should not use server side rendering. You can use the dynamic function from the next/dynamic library.

For example you can wrap your component like this:

import dynamic from 'next/dynamic'

const TestPageWithoutSSR = dynamic(() => import('./TestPage'), {
  ssr: false
})

export default () => <TestPageWithoutSSR />

Surpress Hydration failed error

As a last resort, you can try to suppress the error. The suppressHydrationWarning prop can be used to suppress the hydration warning that is emitted by React when the initial UI rendered on the server does not match the UI rendered on the client after hydration. 

Important:

  • This does not solve the problem, it just hides it.
  • At the time of writing the property is not working properly due to a bug, so in many cases it has no effect.

References

Handling Hydration error in Next.js

Dynamic import in Next.js

 

Share "Fix the React 18: Hydration failed because the initial UI does not match error" with your friends