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

ReactJS报错:TypeError: 无法读取未定义属性'reduce'问题求助

问题排查与修复

错误根源

控制台报错TypeError: Cannot read properties of undefined (reading 'reduce'),说明**dataKey变量在某一时刻变为了undefined**,而非初始的空数组,导致调用数组方法reduce时触发错误,进而引发页面崩溃空白。

代码中的核心问题

  1. 接口返回未做校验:GetData中直接将result.data[1]赋值给dataKey,若接口返回的data数组长度不足2,或result.data[1]本身为undefined,会直接把dataKey从初始空数组改成undefined。
  2. defEndDate的无意义更新:defEndDate在组件每次渲染时都会重新计算(new Date()每次执行生成新对象),导致useEffect的依赖频繁变化,可能触发不必要的接口请求,甚至引发状态异常。
  3. 无空值保护:直接对dataKey调用reduce,未处理dataKey为undefined的边界情况。

修复方案

1. 给dataKey添加空值保护

在调用reduce前确保dataKey是数组:

const hasil = Object.values(
  (dataKey || []).reduce((acc, curr) => {
    // 原reduce逻辑不变
  }, {})
);

2. 缓存defEndDate避免无效更新

用useMemo缓存初始结束日期,确保组件渲染时它的值稳定:

const defEndDate = useMemo(() => new Date().toLocaleDateString("en-US"), []);

3. 接口返回校验

在GetData中校验接口返回的result.data[1],避免将undefined赋值给dataKey:

const GetData = async () => {
  try {
    const result = await getHitApiTotal(StartDate, EndDate);
    // 确保赋值的是数组,不存在则设为空数组
    setDataKey(Array.isArray(result.data[1]) ? result.data[1] : []);
    console.log(result.data[1]);
  } catch (error) {
    console.log(error);
    // 出错时也重置为数组,避免后续报错
    setDataKey([]);
  }
};

4. 可选:添加加载状态

在接口请求期间显示加载提示,提升用户体验的同时避免渲染错误内容:

const [loading, setLoading] = useState(false);

const GetData = async () => {
  setLoading(true);
  try {
    const result = await getHitApiTotal(StartDate, EndDate);
    setDataKey(Array.isArray(result.data[1]) ? result.data[1] : []);
  } catch (error) {
    console.log(error);
    setDataKey([]);
  } finally {
    setLoading(false);
  }
};

// 渲染时判断加载状态
if (loading) return <div>加载中...</div>;

修正后的完整代码片段

import { useState, useEffect, useMemo } from 'react';
import { useRecoilValue, useSetRecoilState } from 'recoil';
// 假设startDate、endDate、getHitApiTotal已正确导入

const HitApiChart = () => {
  const [openModal, setOpenModal] = useState(false);
  const defEndDate = useMemo(() => new Date().toLocaleDateString("en-US"), []);
  const StartDate = useRecoilValue(startDate);
  const EndDate = useRecoilValue(endDate);
  const setStartDate = useSetRecoilState(startDate);
  const setEndDate = useSetRecoilState(endDate);
  const [dataKey, setDataKey] = useState([]);
  const [loading, setLoading] = useState(false);

  const GetData = async () => {
    setLoading(true);
    try {
      const result = await getHitApiTotal(StartDate, EndDate);
      setDataKey(Array.isArray(result.data[1]) ? result.data[1] : []);
      console.log(result.data[1]);
    } catch (error) {
      console.log(error);
      setDataKey([]);
    } finally {
      setLoading(false);
    }
  };

  const hasil = Object.values(
    (dataKey || []).reduce((acc, curr) => {
      const dateStr = curr["@timestamp"].split("T")[0];
      if (!acc[dateStr]) {
        acc[dateStr] = {
          message: curr.message,
          timestamp: dateStr,
          count: 0,
        };
      }
      acc[dateStr].count++;
      return acc;
    }, {})
  );

  const labels = hasil.map((item) => item.timestamp);

  const data = {
    labels,
    datasets: [
      {
        data: hasil.map((item) => item.count),
        borderColor: "rgb(255, 99, 132)",
        backgroundColor: "rgba(255, 99, 132, 0.5)",
        pointRadius: 6,
        xAxisID: "x1",
      },
    ],
    options: {
      plugins: {
        legend: {
          display: false,
        },
      },
    },
  };

  useEffect(() => {
    if (defEndDate !== EndDate) {
      GetData();
    }
  }, [EndDate, StartDate, defEndDate]);

  if (loading) return <div>加载中...</div>;

  return (
    {/* 你的Chart.js组件和日期选择器渲染逻辑 */}
  );
};

export default HitApiChart;

内容的提问来源于stack exchange,提问作者Kia Kalista

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 14:41:44