DEV Community

Kawan Idrees
Kawan Idrees

Posted on

4 1 2 1 1

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:


 javascript
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:


 javascript
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.

SurveyJS custom survey software

Simplify data collection in your JS app with a fully integrated form management platform. Includes support for custom question types, skip logic, integrated CCS editor, PDF export, real-time analytics & more. Integrates with any backend system, giving you full control over your data and no user limits.

Learn more

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

Instrument, monitor, fix: a hands-on debugging session

Join Lazar for a hands-on session where you’ll build it, break it, debug it, and fix it. You’ll set up Sentry, track errors, use Session Replay and Tracing, and leverage some good ol’ AI to find and fix issues fast.

Tune in to the full event

DEV is partnering to bring live events to the community. Join us or dismiss this billboard if you're not interested. ❤️