React问题:为何数组映射的所有子组件都会重渲染?
问题根源与解决方案
问题出在key的使用上
你在映射数组时给ChildItem传的key是每次渲染都重新生成的uuidv4(),这会导致React的diff算法误判:
- 每次Parent组件更新(比如点击Add按钮修改
testArray),所有旧的ChildItem都会被React判定为已卸载,然后重新创建全新的组件实例 - 这种情况下,
memo完全起不到作用,因为组件不是“更新”,而是被重新挂载,自然每个子组件都会执行console.log
修复步骤
用稳定且唯一的key替代动态生成的UUID
你的testArray元素是唯一的数字,直接用元素本身作为key即可:testArray.map(item => { return <ChildItem value={item} key={item} // 替换为元素本身作为key ></ChildItem> })如果后续数组元素是对象,建议用对象自带的唯一标识(比如id字段)作为key,避免使用动态生成的不稳定值。
确保
ChildItem用memo包裹
保持ChildItem的memo处理,这样当valueprops没有变化时,组件不会重渲染: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)优化
addToArray的状态更新(可选但推荐)
用函数式更新获取最新的状态值,避免闭包导致的状态不一致问题:const addToArray = () => { setTestArray(prevArray => [...prevArray, prevArray.length]) } // 按钮点击逻辑简化 <button onClick={addToArray}>Add</button>
验证效果
修改后点击Add按钮,只有新增的那个ChildItem会打印render日志,原有元素的组件不会重渲染。
内容的提问来源于stack exchange,提问作者David Hanimann
相关产品推荐
相关产品推荐

