Chartjs-Using react-chartjs-2 in Gatsby gives me a "cannot read properties of undefined" error in its components

0👍

It looks like SSR (Server-Side Rendering) issues, so when the code is compiled in the Node server it fails.

I’d suggest importing the dependency directly into the client-side dynamically using React.Suspense or loadable components, leaving your code as:

import React from "react"
import { Chart, Arclement, Tooltip, Legend } from 'chart.js'
import loadable from '@loadable/component'
const { Pie } = loadable(() => import('react-chartjs-2'))

const data = {
    labels: ['Taxation', 'Materials', 'Profit', 'Expenses', 'Wages'],
    datasets: [
      {
        label: 'Tax bill',
        data: [25, 20, 8, 12, 34],
      },
    ],
};

const PieChart = () => {
    return (
      <div style={{ width: '750px' }}>
        <Pie data={data} />
      </div>
    );
};

const Artists = (props) => {
    let artistChart = getArtistChart(orderArtists(props.stats));
    return (
        <div id="statsCard">
            <PieChart />
        </div>
    )
}

Or using React.Suspense:

const { Pie } = React.lazy(() => import("react-chartjs-2"));
import React from "react"

const data = {
  labels: ["Taxation", "Materials", "Profit", "Expenses", "Wages"],
  datasets: [
    {
      label: "Tax bill",
      data: [25, 20, 8, 12, 34],
    },
  ],
};

function MyComponent() {
  return (
    <React.Suspense fallback={"Loading"}>
      <div>
        <Pie data={data} />
      </div>
    </React.Suspense>
  );
}

Note: remove the fallback if not needed

Another alternative solution is adding a null loader for the react-chartjs-2 dependency by adding the following in your gatsby-node.js:

exports.onCreateWebpackConfig = ({ stage, loaders, actions }) => {
  if (stage === "build-html" || stage === "develop-html") {
    actions.setWebpackConfig({
      module: {
        rules: [
          {
            test: /react-chartjs-2/,
            use: loaders.null(),
          },
        ],
      },
    })
  }
}

Modified from: https://www.gatsbyjs.com/docs/debugging-html-builds/. In this docs you can also find more information about loadable components

In the snippet above, test is a regular expression (that’s why is between slashes, /) that it should match the folder name inside node_modules of the offending module.

Leave a comment