【问题标题】:How to update multiple states using Immutability Helper | React JS如何使用 Immutability Helper 更新多个状态 |反应 JS
【发布时间】:2018-05-25 05:47:13
【问题描述】:

我是 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

【问题讨论】:

  • 我不熟悉不变性助手,但尝试使用像这样的扩展运算符 { l0: { $set: l0 }, l1: { ...state }}。至于每个条件你只是 l0 或 l1 所以这就是为什么另一个保持默认。
  • @MontyGoldy setState 不会立即修改 this.state 所以当你在 this.setState 之后使用 this.state 时,你实际上得到的是未修改的版本。由于您使用不可变状态,因此您将获得未修改的状态(有关更多信息,请参见答案)。所以使用扩展运算符并不能解决这个问题。
  • 感谢您的参与。 @HMR

标签: javascript node.js reactjs react-state-management react-state


【解决方案1】:

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

来自documentation

setState() 并不总是立即更新组件。它可能 批处理或推迟更新。这使得阅读 this.state 就在调用 setState() 之后,这是一个潜在的陷阱。相反,使用 componentDidUpdate 或 setState 回调(setState(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));

【讨论】:

    【解决方案2】:

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

    我的状态是

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

    我正在更新

    this.setState(
      {...this.state, 
       fields:{name:'', email: '', message: ''}, 
       disabled: false
    });
    

    【讨论】:

    • 如果我使用这种方式,并且我需要 setState 另一个其他状态? ` this.setState( Object.assign(validations, { emailValid: "Email address is not valid." }) , // {loading:false} => Error Here );`
    猜你喜欢
    • 2019-02-05
    • 2020-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-12
    • 2018-12-12
    • 2021-07-26
    • 2021-03-05
    相关资源
    最近更新 更多