javascript - 事件处理程序的状态更新
问题描述
状态无需显式设置即可更新
我偶然跑到这里,这让我很困惑。据我所知,您执行以下操作:
1-创建当前状态的副本 2-修改副本 3-将修改后的副本分配给状态,从而更新它。
我就是这样做的,而且效果很好。
handleChange(index, event) {
const {name, value} = event.target;
this.setState((prevState) => {
const newState = [...prevState.items];
newState[index][name]= value;
return{items: newState};
});
但奇怪和令人困惑的是,下面的代码也可以工作,但不必像上面那样在最后一行显式分配它。只要我更新不是它的引用的副本,它就会更新。
handleChange(index, event) {
const {name, value} = event.target;
this.setState((prevState) => {
const newState = [...prevState.items];
newState[index][name]= value;
return{}; //it works as long as I have the brackets.
});
解决方案
从您问题中的代码来看,您的状态似乎具有类似于以下的结构:
状态= {项目:[{name1:'index0Value1',name2:'index0Value2'},{name1:'index1Value1',name2:'index1Value2'}]};
whereitems
是一个对象数组。
当你这样做时:
const newState = [...prevState.items];
您仅复制数组,但newState
数组中的对象仍与原始状态共享。因此,您可以在不影响原始对象的情况下将新对象推送到数组中,但是当您这样做时:
newState[index][name]= value;
您正在更改原始状态和新状态的对象。运行下面的代码片段来查看演示。
const prevState = { items: [{name1: 'index0Value1', name2: 'index0Value2'}, {name1: 'index1Value1', name2: 'index1Value2'}] };
document.getElementById('origbefore').innerHTML = 'prevState before='+JSON.stringify(prevState);
const newItems = [...prevState.items];
newItems[0]['name1']='tryingToOnlyChangeNewState';
const newState = { items: newItems };
document.getElementById('origafter').innerHTML = 'prevState after='+JSON.stringify(prevState);
document.getElementById('new').innerHTML = 'newState='+JSON.stringify(newState);
<div id="origbefore"></div>
<div id="origafter"></div>
<div id="new"></div>
因此,在这两个示例中,您的分配都在更改 prevState,并且由于setState
支持传入与先前状态合并的部分状态,因此当您返回一个空对象时,React 会将其与突变的先前状态合并,然后重新渲染结果。
推荐阅读
- python - 无法在 Bazel genrule 中使用 Python 的 sh 模块
- raspberry-pi3 - BLE gatttool 从 bluno 读取串行数据?
- javascript - ES6 Classes that depend on each other in static variables
- java - 如何使用spring mvc将参数发送到服务器端并将json返回到数据表
- java - Spring Data Jpa 数据获取,其中父实体在其他实体上有外键
- c# - 如何在c#中以多窗口形式添加相同的计时器
- java - Android Firebase 数据库已损坏
- extjs - 如何在 Touch Sencha 中对齐左侧的单选按钮?
- postgresql - 从 oracle 迁移后 Postgresql 数据库大小变小
- eclipse-plugin - 如何在 RCP 4 应用程序中自定义