【发布时间】:2019-08-22 22:56:59
【问题描述】:
在阅读 React Cookbook 时,我偶然发现了一段代码 sn-p,当用户在 TODO 列表中检查任务是否已完成时,会调用此函数:
markAsCompleted = id => {
// Finding the task by id...
const foundTask = this.state.items.find(task => task.id === id);
// Updating the completed status...
foundTask.completed = true;
// Updating the state with the new updated task...
this.setState({
items: [
...this.state.items,
...foundTask
]
});
}
UPD:不知何故,我完全错过了 foundTask 上的扩展运算符。所以真正发生的是状态只更新了 ...this.state.items (它是变异的),而 ...foundTask 部分没有进入状态,因为它不是有效的传播。
一开始它看起来应该在 items 数组中添加一个新元素,而不是更新,所以我去 JS 控制台检查:
state = { items: [{id: '0', done: false}, {id: '1', done: false}] }
upd = state.items.find(obj => obj.id === '0') // {id: "0", done: false}
upd.done = true // also updates object inside the array
state = { items: [...state.items, upd] }
/* Indeed, adds a new element:
items: Array(3)
0: {id: "0", done: true}
1: {id: "1", done: false}
2: {id: "0", done: true}
*/
那么我已经 downloaded the code 并在本地运行它。而且,令我惊讶的是,它奏效了!状态更新没有任何问题,没有出现额外的元素。我在测试时使用 React DevTools 查看实时状态。
我在网上搜索,但找不到任何像书中那样的例子,但有更好的解释。通常所有解决方案都涉及使用 .map() 构建一个新数组,然后替换现有数组(例如https://stackoverflow.com/a/44524507/10304479)。
我在本书代码 sn-p 和控制台测试之间看到的唯一区别是 React 使用了 .setState(),所以也许这会有所帮助。任何人都可以帮助澄清,为什么它工作?
谢谢!
【问题讨论】:
标签: javascript reactjs ecmascript-6