I get a "hydration failed" error while trying to use Recharts in Nextjs. Has anyone solved this problem before?

Viewed 722

I am just starting a Nextjs project and I want to use a library called Recharts that is popular.

But even a very basic copy paste job from one of its examples throws an error in my NextJS project.

I am expecting this to load a chart. It does that. But then an error pops up showing:

1 of 3 unhandled errors

Unhandled Runtime Error
Error: Hydration failed because the initial UI does not match what was rendered on the server.

Call Stack
throwOnHydrationMismatch
node_modules\react-dom\cjs\react-dom.development.js (14388:0)
tryToClaimNextHydratableInstance
node_modules\react-dom\cjs\react-dom.development.js (14416:0)
updateHostComponent$1
node_modules\react-dom\cjs\react-dom.development.js (20711:0)
beginWork
node_modules\react-dom\cjs\react-dom.development.js (22447:0)

this page mentions something about other errors preceding that msg being the culprit. My console has a few other errors. These ones, in order:

arning: Prop `y` did not match. Server: "5" Client: "10.800000190734863"
    at text
    at Text (webpack-internal:///./node_modules/recharts/es6/component/Text.js:232:5)
    at g
    at Layer (webpack-internal:///./node_modules/recharts/es6/container/Layer.js:23:24)
    at g
    at g
    at Layer (webpack-internal:///./node_modules/recharts/es6/container/Layer.js:23:24)
    at CartesianAxis (webpack-internal:///./node_modules/recharts/es6/cartesian/CartesianAxis.js:77:5)
    at svg
    at Surface (webpack-internal:///./node_modules/recharts/es6/container/Surface.js:23:24)
    at div
    at CategoricalChartWrapper (webpack-internal:///./node_modules/recharts/es6/chart/generateCategoricalChart.js:920:7)
    at SimpleBarChart
    at main
    at div
    at Home

and

next-dev.js?3515:25 Warning: An error occurred during hydration. The server HTML was replaced with client content in <div>.

I've been to a dozen different pages looking for solutions to this but I don't see anything that looks like a solution.

Here is my code:

index.js

import Head from "next/head";
import Image from "next/image";
import styles from "../styles/Home.module.css";

import SimpleBarChart from "../components/rechartsCharts/SimpleBar";

export default function Home() {
    return (
        <div className={styles.container}>
            <Head>
                <title>Create Next App</title>
            </Head>

            <main className={styles.main}>
                <SimpleBarChart></SimpleBarChart>
            </main>

            <footer className={styles.footer}>
                <span>some footer</span>
            </footer>
        </div>
    );
}

and SimpleBarChart.js

import React from "react";
import dynamic from "next/dynamic";
import {
    BarChart,
    Bar,
    XAxis,
    YAxis,
    CartesianGrid,
    Tooltip,
    Legend,
} from "recharts";

const data = [
    {
        name: "Page A",
        uv: 4000,
        pv: 2400,
        amt: 2400,
    },
    {
        name: "Page B",
        uv: 3000,
        pv: 1398,
        amt: 2210,
    },
    {
        name: "Page C",
        uv: 2000,
        pv: 9800,
        amt: 2290,
    },
    {
        name: "Page D",
        uv: 2780,
        pv: 3908,
        amt: 2000,
    },
    {
        name: "Page E",
        uv: 1890,
        pv: 4800,
        amt: 2181,
    },
    {
        name: "Page F",
        uv: 2390,
        pv: 3800,
        amt: 2500,
    },
    {
        name: "Page G",
        uv: 3490,
        pv: 4300,
        amt: 2100,
    },
];

export default function SimpleBarChart() {
    return (
        <BarChart
            id={1}
            width={500}
            height={300}
            data={data}
            margin={{
                top: 5,
                right: 30,
                left: 20,
                bottom: 5,
            }}
        >
            <CartesianGrid strokeDasharray="3 3" />
            <XAxis dataKey="name" />
            <YAxis />
            <Tooltip />
            <Legend />
            <Bar dataKey="pv" fill="#8884d8" />
            <Bar dataKey="uv" fill="#82ca9d" />
        </BarChart>
    );
}

Note that this is copied and pasted in from here so I was really expecting it to "just work" out of the box

Help appreciated

1 Answers

As @juliomalves says, the answer is to use dynamic imports with ssr.

import dynamic from "next/dynamic";

const SimpleBarChartWithoutSSR = dynamic(
        import("../components/rechartsCharts/SimpleBar"),
        { ssr: false }
    );
    const SimpleScatterChartWithoutSSR = dynamic(
        import("../components/rechartsCharts/SimpleScatter"),
        { ssr: false }
    );
    const DashedLineChartWithoutSSR = dynamic(
        import("../components/rechartsCharts/DashedLine"),
        { ssr: false }
    );
    const PercentAreaChartWithoutSSR = dynamic(
        import("../components/rechartsCharts/PercentArea"),
        { ssr: false }
    );

These components worked after that.

Related