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

React TypeScript中排序与映射报错问题求助

Next.js 数组索引映射渲染删除元素崩溃问题

背景与问题

我定义了一个包含两个数组的常量,通过与数组索引一致的 state 值 indexOfFrag,根据常量索引映射数组渲染对应数据:

  • index 0:对应一组元素列表
  • index 1:对应另一组元素列表

点击 index 1 对应的元素时页面崩溃,提示 elements[indexOfFrag] 为 undefined,但 index 0 的元素点击完全正常,报错核心是无法对 undefined 执行 sort 方法。

相关代码

删除元素的处理函数

const handleDeleteElement = ( array: { fid: number; frag: string }[], id: number ) => {
    const newArray = array.filter((element) => element.fid !== id);
    setElements([newArray]);
};

报错的渲染代码

{showDiv && elements[indexOfFrag].sort(() => Math.random() - 0.5).map((frag, i) => (
    <div className={styles.frags} key={i} onClick={() => handleDeleteElement(elements[indexOfFrag], frag.fid)}>
     <h1>{frag.frag}</h1>
    </div>
))}

注:showDiv 是布尔类型 state,用于延迟渲染解决服务端与客户端元素不匹配问题(推测是随机 sort 导致)。

尝试过的无效方案

用 useEffect 提前排序并更新 state,但问题依旧:

useEffect(() => {
    const sortedElements = elements[indexOfFrag].slice().sort(() => Math.random() - 0.5);
     setElements(prevState => {
     const newState = [...prevState];
     newState[indexOfFrag] = sortedElements;
     return newState;});
    setShowDiv(true)
  }, []);

问题原因

核心bug在 handleDeleteElement 的 setElements([newArray]) 这行代码:
它直接把 elements 重置成仅包含当前过滤后数组的新数组。比如处理 index 1 的元素时,原本 elements 是包含两个数组的集合,执行这行后变成 [过滤后的index1数组],此时若 indexOfFrag 仍为 1,elements[1] 自然就是 undefined,触发后续 sort 报错。

修复方案

1. 修正删除函数逻辑

只更新对应索引的数组,保留其他索引的数据:

const handleDeleteElement = (id: number) => {
    setElements(prevElements => {
        // 复制原数组,避免直接修改state
        const newElements = [...prevElements];
        // 对当前indexOfFrag对应的数组进行过滤
        newElements[indexOfFrag] = newElements[indexOfFrag].filter(element => element.fid !== id);
        return newElements;
    });
};

2. 优化渲染代码

{showDiv && elements[indexOfFrag]?.sort(() => Math.random() - 0.5).map((frag) => (
    <div className={styles.frags} key={frag.fid} onClick={() => handleDeleteElement(frag.fid)}>
     <h1>{frag.frag}</h1>
    </div>
))}

优化点:

  • 添加可选链 ?.,防止 elements[indexOfFrag] 为 undefined 时直接报错
  • 把 key 从索引 i 改成唯一标识 frag.fid,避免索引变化导致的渲染异常
  • 移除冗余的数组参数传递,直接利用当前 state 的 indexOfFrag,减少 stale state 风险

3. 解决服务端客户端渲染不匹配问题

将随机排序逻辑放在客户端,依赖 indexOfFrag 和 elements 触发更新:

useEffect(() => {
    if (elements[indexOfFrag]) {
        const sortedElements = [...elements[indexOfFrag]].sort(() => Math.random() - 0.5);
        setElements(prev => {
            const newState = [...prev];
            newState[indexOfFrag] = sortedElements;
            return newState;
        });
        setShowDiv(true);
    }
}, [indexOfFrag, elements]);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 17:27:27