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

React问题:为何数组映射的所有子组件都会重渲染?

问题根源与解决方案

问题出在key的使用上

你在映射数组时给ChildItem传的key是每次渲染都重新生成的uuidv4(),这会导致React的diff算法误判:

  • 每次Parent组件更新(比如点击Add按钮修改testArray),所有旧的ChildItem都会被React判定为已卸载,然后重新创建全新的组件实例
  • 这种情况下,memo完全起不到作用,因为组件不是“更新”,而是被重新挂载,自然每个子组件都会执行console.log

修复步骤

  1. 用稳定且唯一的key替代动态生成的UUID
    你的testArray元素是唯一的数字,直接用元素本身作为key即可:

    testArray.map(item => {
        return <ChildItem
            value={item}
            key={item} // 替换为元素本身作为key
        ></ChildItem>
    })
    

    如果后续数组元素是对象,建议用对象自带的唯一标识(比如id字段)作为key,避免使用动态生成的不稳定值。

  2. 确保ChildItem用memo包裹
    保持ChildItem的memo处理,这样当value props没有变化时,组件不会重渲染:

    import React, { FC, memo } from 'react'
    
    const ChildItem: FC<{ value: number }> = (props) => {
        console.log('render', props.value)
        return <>
            <li>{props.value}</li>
        </>
    }
    
    export default memo(ChildItem)
    
  3. 优化addToArray的状态更新(可选但推荐)
    用函数式更新获取最新的状态值,避免闭包导致的状态不一致问题:

    const addToArray = () => {
        setTestArray(prevArray => [...prevArray, prevArray.length])
    }
    // 按钮点击逻辑简化
    <button onClick={addToArray}>Add</button>
    

验证效果

修改后点击Add按钮,只有新增的那个ChildItem会打印render日志,原有元素的组件不会重渲染。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 17:52:52