React中如何用forEach遍历设多属性并在setState返回解构输出
问题描述
我有一段React状态更新代码,原本手动将row对象的a、b、c属性设为空字符串:
setRows((rows) => rows.map((row) => selected && row.node === selected.id ? { ...row, row.a: "", row.b: "", row.c: "" } : row ) );
现在我有一个名为PossibleValues的常量,存储了这些需要重置的属性名(比如['a', 'b', 'c']),希望通过遍历这个常量来批量设置属性值,避免未来属性增减时需要手动修改代码。但我当前的方法会直接修改原状态:
setRows((rows) => { const row = rows.find( (row) => selected && row.node === selected.id ); if (row) { PossibleValues.forEach( (val) => (row[val] = "") ); } return rows; });
解决方案
要遵循React状态不可变原则,不能直接修改原数组或对象,应该通过创建新对象和数组来更新状态。以下是两种可行的实现方式:
方式一:使用Object.fromEntries构建重置属性对象
setRows((rows) => rows.map((row) => { // 只处理匹配选中id的行 if (selected && row.node === selected.id) { // 把PossibleValues转换为{ 属性名: "" }的键值对对象 const resetProps = Object.fromEntries( PossibleValues.map(prop => [prop, ""]) ); // 展开原row对象,再用重置属性覆盖,返回新对象 return { ...row, ...resetProps }; } // 不匹配的行直接返回原对象 return row; }) );
方式二:使用reduce构建重置属性对象
如果环境不支持Object.fromEntries(比如旧版浏览器),可以用reduce替代:
setRows((rows) => rows.map((row) => { if (selected && row.node === selected.id) { const resetProps = PossibleValues.reduce((acc, prop) => { acc[prop] = ""; return acc; }, {}); return { ...row, ...resetProps }; } return row; }) );
说明
- 上述两种方法都通过
map返回新的数组,对需要修改的行创建新对象,完全不修改原状态,符合React的状态更新规范,能确保组件正确触发重渲染。 - 后续只要维护
PossibleValues常量的内容,增减或修改属性名时,这段代码会自动适配,无需改动更新逻辑。
内容的提问来源于stack exchange,提问作者Anser Waseem
相关产品推荐
相关产品推荐

