You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Next.js中使用Recharts图表组件遭遇类型/空值错误求助

Next.js中使用Recharts图表组件遭遇类型/空值错误求助

刚上手Next.js没几天,想给页面加个图表增强展示效果,选了Recharts结果踩了一连串坑,折腾到现在只能用Chart.js动态创建canvas的方式勉强实现,实在搞不懂为啥直接用Recharts的官方示例代码就报错,来求各位大佬指点!

具体遇到的问题

1. 折线图(LineChart)抛出React子元素类型错误

我直接抄了Recharts官网的LineChart示例代码,放到组件的return里(外层是div套main的常规结构),结果页面直接崩了,报错:

Error: Objects are not valid as a React child (found: object with keys {$$typeof, type, key, props, _owner, _store}). If you meant to render a collection of children, use an array instead.

用的代码是这样的:

<LineChart width={400} height={400} data={data} margin={{ top: 5, right: 20, left: 10, bottom: 5 }}>
  <XAxis dataKey="name" />
  <Tooltip />
  <CartesianGrid stroke="#f5f5f5" />
  <Line type="monotone" dataKey="uv" stroke="#ff7300" yAxisId={0} />
  <Line type="monotone" dataKey="pv" stroke="#387908" yAxisId={1} />
</LineChart>

测试用的data:

const data = [
  { name: 'Original Price', price: 100 },
  { name: 'Reduced Price', price: 50 },
];

2. 柱状图(BarChart)抛出空值错误

后来换了BarChart试试,用了带ResponsiveContainer的代码,结果又报另一个错:

TypeError: resolveDispatcher() is null

对应的代码:

<ResponsiveContainer width="100%" height={300}>
  <BarChart data={data} margin={{ top: 20, right: 30, left: 20, bottom: 5 }}>
    <XAxis dataKey="name" />
    <YAxis />
    <Tooltip formatter={(value) => `$${value}`} />
    <Legend />
    <Bar dataKey="price" fill="#8884d8" />
  </BarChart>
</ResponsiveContainer>

3. 绕路的临时解决方案

最后没办法,改用Chart.js动态创建canvas的方式,居然成功渲染出了图表:

async function createBarChart() {
  const data = [
    { year: 2010, count: 10 },
    { year: 2011, count: 20 },
    { year: 2012, count: 15 },
    { year: 2013, count: 25 },
    { year: 2014, count: 22 },
    { year: 2015, count: 30 },
    { year: 2016, count: 28 },
  ];
  // 动态创建canvas元素
  const canvas = document.createElement('canvas');
  canvas.width = 400;
  canvas.height = 200;
  document.body.appendChild(canvas);
  // 基于canvas创建图表
  new Chart(
    canvas.getContext('2d'),
    {
      type: 'bar',
      data: {
        labels: data.map(row => row.year),
        datasets: [
          {
            label: 'Counts by Year',
            data: data.map(row => row.count),
            backgroundColor: 'rgba(75, 192, 192, 0.6)',
          }
        ]
      },
      options: {
        responsive: false, // 因为canvas尺寸是固定的
      }
    }
  );
};

我的猜测和疑问

目前自己瞎猜是不是Next.js的服务端渲染(SSR)和Recharts的组件渲染逻辑冲突了?毕竟直接把Recharts组件放到return里,服务端渲染的时候可能没法正确处理React元素,才抛出了类型错误?

另外那个resolveDispatcher() is null的错误,查了下好像和React的useContext钩子在错误时机调用有关,难道Recharts内部用了某些在SSR环境下不能正常运行的React特性?

有没有大佬遇到过一模一样的情况?能不能教教我怎么在Next.js里正确使用Recharts的组件,不想一直用这种动态创建canvas的绕路方式啊😭

内容来源于stack exchange

火山引擎 最新活动