Next.js中如何精准更新数组指定索引而非全部索引?
问题修复方案
核心问题分析
- 对象引用复用:初始化时
tempReadMoreData定义在forEach循环外部,每次循环仅修改该对象属性后推入数组,导致readMoreState中所有元素指向同一个对象引用,修改任意索引的状态都会同步影响其他索引。 - 数组元素引用重复:使用
Array.fill()填充数组时,所有位置的元素都是同一个对象的引用,后续修改某一索引元素时,其他位置元素也会被动改变。
1. 修复初始化逻辑(useEffect部分)
将tempReadMoreData的定义移至forEach循环内部,确保每个package对应独立对象;同时用Array.from()替代Array.fill(),保证数组内每个元素都是独立对象:
const [readMoreState, setReadMoreState] = useState<readMoreStateAttributes[]>([]); useEffect(()=>{ const tempReadMoreArray: readMoreStateAttributes[] = []; temporaryPackageData?.forEach((packageList, packageIndex)=>{ // 每次循环创建新对象,避免跨package引用复用 const tempReadMoreData:readMoreStateAttributes = { textReadMore: [], plainReadMore: [], checkBoxReadMore:[], multipleReadMore:[], fileReadMore:[], dateReadMore:[] }; const questionCount = packageList?.questions?.length || 0; // 用Array.from生成独立对象,避免fill导致的引用重复 tempReadMoreData.plainReadMore = Array.from({length: questionCount}, () => ({ questionType: 'Plain' as questionTypeAttributes, selectedIndex: null })); tempReadMoreData.textReadMore = Array.from({length: questionCount}, () => ({ questionType: 'Text' as questionTypeAttributes, selectedIndex: null })); tempReadMoreData.checkBoxReadMore = Array.from({length: questionCount}, () => ({ questionType: 'Checkbox' as questionTypeAttributes, selectedIndex: null })); tempReadMoreData.dateReadMore = Array.from({length: questionCount}, () => ({ questionType: 'Date' as questionTypeAttributes, selectedIndex: null })); tempReadMoreData.fileReadMore = Array.from({length: questionCount}, () => ({ questionType: 'File' as questionTypeAttributes, selectedIndex: null })); tempReadMoreData.multipleReadMore = Array.from({length: questionCount}, () => ({ questionType: 'Multiple choice' as questionTypeAttributes, selectedIndex: null })); tempReadMoreArray.push(tempReadMoreData); }); setReadMoreState(tempReadMoreArray); }, [temporaryPackageData?.length])
2. 修复状态更新函数(handleReadMoreFunc)
移除不必要的遍历,精准定位目标package,通过层级拷贝确保仅修改目标索引的状态:
const handleReadMoreFunc = (params: { questionEvent: questionTypeAttributes, packageIndex: number, questionIndex: null | number, readMoreAction: 'Read More' | 'Read Less', targetIndex?: number })=>{ const {questionEvent, packageIndex, questionIndex, readMoreAction} = params; if (questionIndex === null) return; // 仅拷贝并修改目标package,其他package保持原引用 const result = readMoreState.map((item, idx) => { if (idx !== packageIndex) return item; // 拷贝目标package对象及对应类型数组,避免引用修改 const updatedPackage = {...item}; const updatedTextReadMore = [...updatedPackage.textReadMore]; // 更新目标question的状态 updatedTextReadMore[questionIndex] = { questionType: 'Text' as questionTypeAttributes, selectedIndex: readMoreAction === 'Read More' ? questionIndex : null }; updatedPackage.textReadMore = updatedTextReadMore; return updatedPackage; }); setReadMoreState(result); }
内容的提问来源于stack exchange,提问作者valve
相关产品推荐
相关产品推荐

