DEV Community

Kawan Idrees
Kawan Idrees

Posted on

Power of useLayoutEffect for solving Hydration error in Next js.

If you've worked with Next.js before, you may have encountered the dreaded "Text content did not match" error, also known as a hydration error. This error occurs when the HTML generated on the server does not match the HTML generated on the client during the first render. One common cause of this error is the use of useEffect to update the state, which causes a flicker or jarring effect on the page.

Image description

Fortunately, there is a solution to this problem: useLayoutEffect. This hook has the same signature as useEffect, but it runs synchronously after all DOM mutations. This means that it is guaranteed to run before the browser can paint anything on the screen, making it perfect for handling hydration errors.

Let's take a look at an example. Suppose you have a component that sets the active category in local storage when the user clicks on a button:

import { useState } from 'react';

const MyComponent = () => {
  const [activeCategory, setActiveCategory] = useState('A');

  const handleClick = (category) => {
    setActiveCategory(category);
    localStorage.setItem('activeCategory', category);
  };

  return (
    <div>
      <button onClick={() => handleClick('A')}>Category A</button>
      <button onClick={() => handleClick('B')}>Category B</button>
      <button onClick={() => handleClick('C')}>Category C</button>
    </div>
  );
};

Enter fullscreen mode Exit fullscreen mode

This code works fine during the initial render, but if you navigate away from the page and then come back, the active category will be reset to 'A' because the state is being reset to its initial value. To fix this problem, you can use useLayoutEffect to set the active category in local storage:

import { useState, useLayoutEffect } from 'react';

const MyComponent = () => {
  const [activeCategory, setActiveCategory] = useState('A');

  useLayoutEffect(() => {
    localStorage.setItem('activeCategory', activeCategory);
  }, [activeCategory]);

  const handleClick = (category) => {
    setActiveCategory(category);
  };

  return (
    <div>
      <button onClick={() => handleClick('A')}>Category A</button>
      <button onClick={() => handleClick('B')}>Category B</button>
      <button onClick={() => handleClick('C')}>Category C</button>
    </div>
  );
};
Enter fullscreen mode Exit fullscreen mode

Now, when the user clicks on a button, the active category is updated in the state, and then useLayoutEffect runs and sets the active category in local storage. This ensures that the active category is preserved even if the user navigates away from the page and then comes back.

In conclusion, useLayoutEffect is a powerful tool for handling hydration errors in Next.js. Using it instead of useEffect ensures that your state updates are reflected correctly on the client during the first render, and avoids the dreaded "Text content did not match" error.

Top comments (0)