在Gatsby中使用react-chartjs-2会在其组件中出现“无法读取未定义的属性”错误

klsxnrf1  于 2022-11-06  发布在  Chart.js
关注(0)|答案(1)|浏览(115)

我尝试在Gatsby项目中使用react-chartjs-2。我按照this website编写了第一个测试,看看它是否有效。我的代码是:

import React from "react"
import { Chart, Arclement, Tooltip, Legend } from 'chart.js'
import { Pie } from '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>
    )
}

我得到以下错误:

Uncaught TypeError: Cannot read properties of undefined (reading 'prototype')
    at TypedRegistry.isForType (chart.esm.js:4756:1)
    at Registry._getRegistryForType (chart.esm.js:4899:1)
    at eval (chart.esm.js:4879:1)
    at Array.forEach (<anonymous>)
    at Registry._each (chart.esm.js:4878:1)
    at Registry.add (chart.esm.js:4836:1)
    at Chart.value [as register] (chart.esm.js:6169:1)
    at eval (webpack-internal:///./src/pages/elements/artists.jsx:17:45)
    at ./src/pages/elements/artists.jsx (component---src-pages-index-js.js:62:1)
    at options.factory (commons.js:3711:31)

它是由盖茨比内部使用图表的错误方式引起的还是可以按现在的方式修复的?

w8biq8rn

w8biq8rn1#

这看起来像是SSR(Sserver-SideRendering)问题,因此在节点服务器中编译代码时会失败。
我建议使用React.Suspenseloadable components动态地将依赖项直接导入客户端,代码如下所示:

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>
    )
}

或者使用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>
  );
}
  • 注:如果不需要,请删除fallback *

另一个替代解决方案是通过在gatsby-node.js中添加以下内容来为react-chartjs-2依赖项添加null加载程序:

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

在上面的代码片段中,test是一个正则表达式(这就是为什么在斜杠之间,/),它应该匹配出错模块的node_modules中的文件夹名称。

相关问题