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

React项目启动报错'Cannot read properties of undefined (reading filter)'排查求助

React运行时错误:Cannot read properties of undefined (reading 'filter') 排查与修复

需要提供的文件

  • hooks/useCard.js:错误明确发生在这个自定义钩子内部,必须查看其代码才能精准定位问题。

问题定位步骤

  1. 锁定错误来源:错误栈显示TypeError触发于useCard钩子,说明是在该钩子内部对某个undefined值调用了.filter()方法。
  2. 检查cards状态流转:App.jsx中cards初始值为数组[],但如果接口请求返回的response.data是undefined,会通过setCard将cards变为undefined,进而导致useCard处理时出错。
  3. 排查useCard逻辑:找到钩子中所有调用.filter()的代码行,确认调用对象是否存在未处理的undefined情况。

修复方案

方案1:确保cards始终为数组

在接口请求后,强制将response.data转为数组,避免cards变成undefined:
修改App.jsx中的fetchCard函数:

const [fetchCard, cardLoading, cardError] = useFetching(async () => {
    const response = await CadrService.getAll(limit, page);
    // 确保data是数组,不存在则设为空数组
    setCard(Array.isArray(response.data) ? response.data : [])
    setTotalCount(response.headers['x-total-count'])
})

方案2:在useCard钩子中做防御性处理

在useCard内部先判断传入的cards是否为数组,若不是则直接返回空数组:

// hooks/useCard.js
import { useMemo } from 'react';

export const useCard = (cards, sort, query) => {
    // 防御性检查:确保cards是数组
    const safeCards = Array.isArray(cards) ? cards : [];

    const sortedCards = useMemo(() => {
        let result = [...safeCards];
        if (sort) {
            // 按你的实际排序逻辑调整,示例为按字段字符串排序
            result = result.sort((a, b) => a[sort].localeCompare(b[sort]));
        }
        return result;
    }, [safeCards, sort]);

    const sortedAndSearchCards = useMemo(() => {
        return sortedCards.filter(card => {
            // 按你的实际搜索逻辑调整,示例为标题包含查询词
            return card.title.toLowerCase().includes(query.toLowerCase());
        });
    }, [sortedCards, query]);

    return sortedAndSearchCards;
};

方案3:完善接口错误处理

确保useFetching钩子包含错误捕获逻辑,避免请求失败时response为undefined:

// hooks/useFetching.js
import { useState } from 'react';

export const useFetching = (callback) => {
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState('');

    const fetching = async (...args) => {
        try {
            setLoading(true);
            await callback(...args);
        } catch (e) {
            setError(e.message);
            // 可在此添加错误提示逻辑
        } finally {
            setLoading(false);
        }
    };

    return [fetching, loading, error];
};

解决“看不到文件名和行号”的问题

  • 确保项目处于开发模式(执行npm start启动,而非npm run build),开发模式默认生成Source Map,浏览器开发者工具的Sources标签中可直接查看原文件(如hooks/useCard.js),而非打包后的bundle.js。
  • 若仍无法看到原文件,检查构建工具配置:
    • Webpack:确保devtool设置为'eval-cheap-module-source-map'(开发模式推荐)。
    • Vite:默认开发模式已开启Source Map,无需额外配置。

内容的提问来源于stack exchange,提问作者Андрей

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 10:45:01