1

我是 Immutability Helper React 库的新手,我正在尝试同时更新多个状态值,但只有最后一个调用方法状态正在更新。

这是我尝试过的:

state : {l0: null, l1: null}
updateL0 = (l0) => {
    if(l0){
      this.setState(
        update(this.state, {
          l0: { $set: l0 }
        })
      );
    }
  };
  updateL1 = (l1) => {
    if(l1){
      this.setState(
        update(this.state, {
          l1: { $set: l1 }
        })
      );
    }
  };

Current Output: l1: null, l2: Expected Value

Expected Output: l1: Expected Value , l2: Expected Value
4

2 回答 2

3

您不能在一个事件处理程序中多次 setStatethis.state可能会在 setState 之后异步更新。

文档

setState() 并不总是立即更新组件。它可能会批量更新或将更新推迟到以后。这使得在调用 setState() 之后立即读取 this.state 是一个潜在的陷阱。相反,使用 componentDidUpdate 或 setState 回调 (setState(updater, callback)),它们都保证在应用更新后触发。如果您需要根据之前的状态设置状态,请阅读下面的 updater 参数。

setState 的行为如下:

//sate is {name:"Ben",age:22}
this.setState({...this.state,age:23});
console.log(this.state.age);//will log 22

因此,如果您在一个事件处理程序中多次设置状态,您可能无法获得您希望的结果:

//sate is {name:"Ben",age:22}
this.setState({...this.state,age:23});
console.log(this.state.age);//will log 22
this.setState({...this.state,name:"Harry"});//age will still be 22

更好的解决方案是不使用回调,而是将函数编写为纯函数(没有 setState 之类的副作用),将状态传递给函数并让它们返回新状态:

updateL0 = (state,l0) => {
  if(l0){
    return update(
      state,
      {
        l0: { $set: l0 }
      }
    );
  }
  return state;
};
updateL1 = (state,l1) => {
  if(l1){
    return update(
      state, 
      {
        l1: { $set: l1 }
      }
    );
  }
  return state;
};
//when you call it you can do:
const newState = updateL0(this.state,L0);
this.setState(updateL1(newState,L1));//note that I'm passing newState here
//or you can just nest updateL1 and updateL0
this.setState(updateL1(updateL0(this.state,L0),L1));
于 2018-05-25T07:59:12.690 回答
0

在 setState 方法中使用spread operator (...)以下方式更新多个状态字段

我的状态是

this.state ={
       fields: {
         name:'',
         email: '',
         message: ''
       },
       errors: {},
       disabled : false
} 

我正在更新

this.setState(
  {...this.state, 
   fields:{name:'', email: '', message: ''}, 
   disabled: false
});
于 2018-11-04T16:37:20.627 回答