React中更新对象内字符串数组时State不触发重渲染的解决方法
问题根源与解决方法
你遇到的这个问题,核心是直接修改了React state的原引用,导致React无法检测到状态变化,所以没触发重渲染。
咱们看你写的handleAddOption函数:
let newArray = data; newArray.map((item: any, i: number) => { if (i === questionIndex) { newArray[questionIndex].options.push(''); } }); setData(newArray);
这里newArray = data只是把原state数组的引用赋值给了新变量,本质上两个变量指向的是同一个数组对象。你修改newArray[questionIndex].options的时候,是直接在原state的数组上做修改(属于mutate操作),最后调用setData(newArray)时,数组的引用根本没变化,React会觉得“状态没更新”,自然不会触发组件重渲染。
解决方法:用不可变的方式更新state
React要求我们更新state时,必须创建新的引用(新数组/新对象),而不是修改原数据。这里有两种常用的写法:
写法一:用map创建新数组并拷贝修改项
const handleAddOption = (questionIndex: number) => { // 通过map生成新数组,只修改目标项,其他项保持原样 const newArray = data.map((item, i) => { if (i === questionIndex) { // 拷贝当前question对象,并生成新的options数组 return { ...item, options: [...item.options, ''] // 用扩展运算符创建新数组,添加空字符串 }; } return item; }); setData(newArray); };
写法二:先拷贝整个数组,再替换目标项
const handleAddOption = (questionIndex: number) => { // 先拷贝原数组,得到新的数组引用 const newArray = [...data]; // 拷贝要修改的question对象,同时更新它的options数组 const updatedQuestion = { ...newArray[questionIndex], options: [...newArray[questionIndex].options, ''] }; // 用新的question对象替换数组中的原项 newArray[questionIndex] = updatedQuestion; // 更新state setData(newArray); };
这两种写法的核心都是:不修改原state的任何部分,而是创建新的数组/对象来承载更新后的数据,这样React就能检测到state的引用变化,触发组件重渲染,你添加的新option就会显示出来了。
内容的提问来源于stack exchange,提问作者Higor Alves
相关产品推荐
相关产品推荐

