AzeaL87
AzeaL87

Reputation: 85

How To Solve React Hydration Error in Next

I keep getting an error saying "Hydration failed because the initial UI does not match what was rendered on the server."

I have no idea what is causing the error so I was hoping someone else may know what is wrong. I think I narrowed down where the error is happening and posted the code below of where I think it breaks. If any more code is needed let me know.

Thanks in advance for all the help.

import React, { useEffect } from "react";
import styles from "../../styles/Home.module.css";
import Coin from "../Coin/Coin";

type CoinListProps = {
  coins: any;
};

const CoinList = ({ coins }: CoinListProps) => {
  useEffect(() => {
    console.log(coins);
  }, []);

  return (
    <div className={styles.coinList}>
      <table>
        <tr>
          <th>Coin</th>
          <th>Price</th>
          <th>24h</th>
        </tr>
        {coins.map((coin: any, index: any) => (
          <Coin key={index} coin={coin} />
        ))}
      </table>
    </div>
  );
};

export default CoinList;

Upvotes: 8

Views: 24738

Answers (3)

GROVER.
GROVER.

Reputation: 4378

Update (as of 2024)

Although this answer will help in certain situations, such as where formatting may occur in the browser after being rendered on the server, it is only a band-aid solution for most other valid hydration errors.

@sms was on the right track; before you attempt to use the suppressHydrationWarning prop, you should check the syntax of your HTML, as HTML syntax issues are very easy to miss.

For example, a button nested within an anchor tag will throw this same error, and is often a simple fix. Likewise with a p tag inside of another p tag (common when working with CMS's).

Make sure you check this before using my solution.


If you want to suppress a hydration warning on a given component, you can pass the suppressHydrationWarning prop to it.

This signals to React that the component's content may be different once the page is re-rendered on the client side and to ignore the error.

<Coin key={index} coin={coin} suppressHydrationWarning />

See Suppress Hydration Warning (React Docs):

If you set suppressHydrationWarning to true, React will not warn you about mismatches in the attributes and the content of that element. It only works one level deep and is intended to be used as an escape hatch. Don’t overuse it. You can read more about hydration in the ReactDOM.hydrateRoot() documentation.

Upvotes: 9

Jerald Baroro
Jerald Baroro

Reputation: 106

Aside from the answer of @sms, for other hydration errors, I have this very handy fix:

const [hydrated, setHydrated] = useState(false);

useEffect(() => {
  // this forces a rerender
  setHydrated(true)
}, [])

if(!hydrated) {
  // this returns null on first render, so the client and server match
  return null
}

Works everytime.

Upvotes: 3

sms
sms

Reputation: 1440

I think you probably missed tbody in table. This will cause an error in NextJS. Try:

<table>
    <tbody>
        <tr>
            <th>Coin</th>
            <th>Price</th>
            <th>24h</th>
        </tr>
        {coins.map((coin: any, index: any) => (
            <Coin key={index} coin={coin} />
        ))}
    </tbody>
</table>

Upvotes: 3

Related Questions