使用JavaScript map()函数更新多个对象的React组件重构疑问
解决React中用map更新多个对象属性的问题
嘿,我来帮你理清这个问题!你遇到的语法错误主要是因为在return()里直接写了两个没有分隔、不符合表达式规则的赋值语句,而且用map来做修改外部对象的操作其实也不是它的最佳用途,咱们一步步来解决:
首先修复语法错误
你原来的写法里,return (initData[${day}From] = ... initData[${day}To] = ...) 存在两个问题:
- 两个赋值语句之间没有分号分隔,JS会把它们解析成一个非法的表达式;
return()的括号里只能容纳单个表达式,多个语句不能直接这么放。
如果一定要用map完成这个操作(虽然不推荐,后面说原因),你可以把赋值放在代码块里,然后返回一个无关的值(因为map要求必须返回元素):
days.map(day => { // 把两个赋值放在代码块里,不需要用return包裹 initData[`${day}From`] = myStr.slice(0, 2); initData[`${day}To`] = myStr.slice(5, 7); // map需要返回值,这里可以返回任意值,比如day或者undefined return day; });
更合适的写法:用forEach代替map
map的设计初衷是遍历数组并返回一个新数组,用来做“转换元素”的操作;而你现在只是想遍历days来修改外部的initData,这属于“执行副作用”,用forEach会更贴合语义,也不需要强制返回值:
days.forEach(day => { initData[`${day}From`] = myStr.slice(0, 2); initData[`${day}To`] = myStr.slice(5, 7); });
如果initData是React State:必须用不可变更新
如果initData是React的state变量,那你绝对不能直接修改它(React依赖state的不可变性来检测更新)。这时候应该用reduce生成一个新的对象,再通过setState更新:
// 复制原state的所有属性,再添加/覆盖新的属性 const updatedData = days.reduce((acc, day) => { return { ...acc, [`${day}From`]: myStr.slice(0, 2), [`${day}To`]: myStr.slice(5, 7) }; }, { ...initData }); // 用setState更新(类组件)或者set函数(函数组件) setInitData(updatedData);
这种写法完全符合React的状态更新规范,不会出现意外的渲染问题。
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

