You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React使用ApexCharts传递数组时触发TypeError错误求助

React + ApexCharts 数据传递 TypeError 问题解决

出现的错误

错误1:Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'x')

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'x')
 at t.value (apexcharts.common.js:6:113947)
    at t.value (apexcharts.common.js:6:113596)
    at t.value (apexcharts.common.js:6:120591)
    at t.value (apexcharts.common.js:6:123454)
    at t.value (apexcharts.common.js:15:37106)
    at t.eval [as create] (apexcharts.common.js:6:4473)
    at eval (apexcharts.common.js:15:36106)
    at new Promise (<anonymous>)
    at t.value (apexcharts.common.js:15:21675)
    at r.value (react-apexcharts.min.js:1:2927)
    at safelyCallComponentDidMount (react-dom.development.js:22877:14)
    at reappearLayoutEffectsOnFiber (react-dom.development.js:23531:11)
    at reappearLayoutEffects_complete (react-dom.development.js:24833:7)
    at reappearLayoutEffects_begin (react-dom.development.js:24821:7)
    at commitLayoutEffects_begin (react-dom.development.js:24644:11)
    at commitLayoutEffects (react-dom.development.js:24607:3)
    at commitRootImpl (react-dom.development.js:26818:5)
    at commitRoot (react-dom.development.js:26677:5)
    at finishConcurrentRender (react-dom.development.js:25976:9)
    at performConcurrentWorkOnRoot (react-dom.development.js:25804:7)
    at workLoop (scheduler.development.js:266:34)
    at flushWork (scheduler.development.js:239:14)
    at MessagePort.performWorkUntilDeadline (scheduler.development.js:533:21)

错误2:Unhandled Runtime Error TypeError: Cannot read properties of undefined (reading 'toString')

Unhandled Runtime Error TypeError: Cannot read properties of undefined (reading 'toString')
 at t.value (apexcharts.common.js:6:390713)
    at t.value (apexcharts.common.js:6:387088)
    at t.value (apexcharts.common.js:15:36720)
    at t.eval [as create] (apexcharts.common.js:6:4473)
    at eval (apexcharts.common.js:15:36106)
    at new Promise (<anonymous>)
    at t.value (apexcharts.common.js:15:21675)
    at r.value (react-apexcharts.min.js:1:2927)
    at invokeLayoutEffectMountInDEV (react-dom.development.js:25128:22)
    at invokeEffectsInDev (react-dom.development.js:27346:11)
    at commitDoubleInvokeEffectsInDEV (react-dom.development.js:27322:5)
    at flushPassiveEffectsImpl (react-dom.development.js:27051:5)
    at flushPassiveEffects (react-dom.development.js:26979:14)
    at eval (react-dom.development.js:26764:9)
    at workLoop (scheduler.development.js:266:34)
    at flushWork (scheduler.development.js:239:14)
    at MessagePort.performWorkUntilDeadline (scheduler.development.js:533:21)

相关代码

页面组件(Axios请求+组件调用)

import Head from 'next/head';
import { Box, Container, Unstable_Grid2 as Grid } from '@mui/material';
import { Layout as DashboardLayout } from 'src/layouts/dashboard/admin/layout';
import axios from 'axios';
import { useEffect, useState } from 'react';
import { TotalSalesChart } from '../../sections/overview/Admin/TotalSalesChart';


const Page = () => {
  const [currentMonth, setCurrentMonth] = useState([]);
  const [data, setData] = useState([]);
  const [totalSalesArray, setTotalSalesArray] = useState([]);

  useEffect(() => {
    axios.get('http://localhost:8001/admin/getSalesPerMonth', { withCredentials: true })
         .then((response) => {
           setCurrentMonth(response.data['currentMonth']);
           setData(response.data['pastMonths']);
         }).catch((error) => {
      console.log(error);
    });
  },[]);
  const totalSales = currentMonth[0]?.totalSales;

  useEffect(() => {
    const salesArray = Object.values(data).map(month => month.totalSales);
    setTotalSalesArray([...salesArray.reverse(), totalSales]);
  }, [data]);
  return (
    <>
      <Head>
        <title>
          Overview
        </title>
      </Head>
      <Box
        component="main"
        sx={{
          flexGrow: 1,
          py: 8
        }}
      >
        <Container maxWidth="xl">
          <Grid
            container
            spacing={3}
          >
            <Grid
              xs={12}
              lg={8}
            >
              <TotalSalesChart
                chartSeries={[
                  {
                    name: 'This year',
                    data: totalSalesArray
                  }
                ]}
              />
            </Grid>
          </Grid>
        </Container>
      </Box>
    </>
  );
};

Page.getLayout = (page) => (
  <DashboardLayout>
    {page}
  </DashboardLayout>
);

export default Page;

图表组件代码

import DotsHorizontalIcon from '@untitled-ui/icons-react/build/esm/DotsHorizontal';
import { Box, Card, CardContent, CardHeader, IconButton, SvgIcon } from '@mui/material';
import { useTheme } from '@mui/material/styles';
import { Chart } from '../../../components/chart';
import { Scrollbar } from '../../../components/scrollbar';

const useChartOptions = () => {
  const theme = useTheme();

  return {
    chart: {
      background: 'transparent',
      stacked: false,
      toolbar: {
        show: false
      },
      zoom: {
        enabled: false
      }
    },
    colors: [theme.palette.primary.main],
    dataLabels: {
      enabled: false
    },
    fill: {
      gradient: {
        opacityFrom: 0.4,
        opacityTo: 0.1,
        stops: [0, 100]
      },
      type: 'gradient'
    },
    grid: {
      borderColor: theme.palette.divider,
      strokeDashArray: 2,
      xaxis: {
        lines: {
          show: false
        }
      },
      yaxis: {
        lines: {
          show: true
        }
      }
    },
    markers: {
      size: 6,
      strokeColors: theme.palette.background.default,
      strokeWidth: 3
    },
    stroke: {
      curve: 'smooth'
    },
    theme: {
      mode: theme.palette.mode
    },
    xaxis: {
      axisBorder: {
        show: false
      },
      axisTicks: {
        show: false
      },
      categories: [
        'Jan',
        'Feb',
        'Mar',
        'Apr',
        'May',
        'Jun',
        'Jul',
        'Aug',
        'Sep',
        'Oct',
        'Nov',
        'Dec'
      ],
      labels: {
        offsetY: 5,
        style: {
          colors: theme.palette.text.secondary
        }
      }
    },
    yaxis: {
      labels: {
        formatter: (value) => (value > 0 ? `${value}` : `${value}`),
        offsetX: -10,
        style: {
          colors: theme.palette.text.secondary
        }
      }
    }
  };
};

export const TotalSalesChart = (props) => {
  const { chartSeries } = props;
  const chartOptions = useChartOptions();

  return (
    <Box
      sx={{
        backgroundColor: (theme) => theme.palette.mode === 'dark'
          ? 'neutral.800'
          : 'neutral.100',
        p: 3
      }}
    >
      <Card>
        <CardHeader
          action={(            <IconButton>
              <SvgIcon>
                <DotsHorizontalIcon/>
              </SvgIcon>
            </IconButton>
          )}
          title="Sales chart"
        />
        <CardContent>
          <Scrollbar>
            <Box
              sx={{
                height: 375,
                minWidth: 500,
                position: 'relative'
              }}
            >
              <Chart
                height={350}
                options={chartOptions}
                series={chartSeries}
                type="area"
              />
            </Box>
          </Scrollbar>
        </CardContent>
      </Card>
    </Box>
  );
};

数据示例

totalSalesArray有效数据示例:

[6020, 6890, 600, 600, 60, 60, 60, 750, 750, 7550, 232, 1500]

问题原因与修复方案

原因分析

ApexCharts无法处理数据数组中的undefined值。代码中存在两个核心问题:

  1. 初始渲染时totalSales为undefined(currentMonth初始是空数组,currentMonth[0]?.totalSales返回undefined),导致totalSalesArray混入无效值。
  2. 第二个useEffect依赖项缺失totalSales,当currentMonth更新后,totalSales变化不会触发数组更新,造成数据不同步。

修复步骤

  1. 给totalSales设置默认值,避免undefined:
const totalSales = currentMonth[0]?.totalSales ?? 0;
  1. 调整第二个useEffect的依赖项,加入totalSales,同时给map中的month.totalSales设置默认值:
useEffect(() => {
  const salesArray = Object.values(data).map(month => month.totalSales ?? 0);
  setTotalSalesArray([...salesArray.reverse(), totalSales]);
}, [data, totalSales]);
  1. (可选)添加加载状态,避免数据未准备好时渲染图表:
    在页面组件中,仅当totalSalesArray长度匹配x轴分类数(12)时再渲染图表:
{totalSalesArray.length === 12 && (
  <TotalSalesChart
    chartSeries={[
      {
        name: 'This year',
        data: totalSalesArray
      }
    ]}
  />
)}

内容的提问来源于stack exchange,提问作者Ahmed Haitham

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 02:35:02