首页 文章

React setState()保证

提问于
浏览
0

在setState的文档中,它有这样的说法:

setState()不会立即改变this.state,但会创建挂起状态转换 . 调用此方法后访问this.state可能会返回现有值 . 无法保证对setState的调用同步操作,并且可以对调用进行批处理以提高性能 .

所以我理解你是否有像这样的事件处理程序:

handleClick() {
  this.stuff1();
  this.stuff2();
}

stuff1() {
  this.setState({...});
}

stuff2() {
  doSomethingWithState(this.state);
  this.setState({...});
}

然后在stuff2方法中你可能没有(或者这保证你不会......)从stuff1看到状态更新 . React提供了一种通过向setState()而不是对象提供函数来“安全地”访问先前状态的方法 . 但是大概你可以通过在处理事件时自己跟踪状态并在方法结束时调用setState()一次来解决这个问题 . 因此,为setState()提供函数可能还有另一个原因选项 . 如果在调用handleClick方法之前可以对状态进行其他更改,该怎么办?

例如,如果handleClick()被调用两次,那么我是否能保证在第二次调用handleClick()时看到第一次调用handleClick()的状态变化?还是有其他方式在调用事件处理程序之前状态可能变脏?

3 回答

  • 0

    如果我理解你正确,那么答案是否定的,你不能保证,因为setState是一个异步操作 - 所以它有点像你提到的第一个'问题' . 您可以为setState方法提供回调函数,该函数将在setState方法完成时触发 . 然后,在回调范围内,您可以保证更新当前状态并提供旧状态以进行比较和其他内容....

  • 2

    如上所述,您可以提供回调 . 或者,因为您希望在handleClick()中执行第一个函数,所以您可以在第一个函数中设置状态后调用第二个函数 . 即,

    handleClick() {
      this.stuff1();
    }
    
    stuff1() {
      this.setState({...}, 
        () => { 
          this.stuff2(); 
        });
    }
    
    stuff2() {
      doSomethingWithState(this.state);
      this.setState({...});
    }
    

    我认为这将为提出的问题提供解决方案 . 因为我们不能保证对 setState 的调用的同步操作,因为它是一个异步操作 .

  • 1

    只要你没有使用回调函数和传入一个对象,只要你有一个从前一个状态派生的状态,就会遇到一个不同步的问题 . 在您的上一个示例中,只有使用该函数才能保证 . 如果您依赖于 this.state ,您可能很容易遇到 handleClick 被调用一次的情况,状态转换排队等待以后解决,您再次调用 handleClick 并且第一个状态更改仍处于待处理状态并且在队列中,所以当您调用 this.state 它将具有与第一个 handleClick 相同的状态,这不是你想要的 .

    这将是使用回调函数的一个示例,假设 doSomethingWithState 返回更新的状态对象并且当然不是变异的 .

    stuff2() {
      this.setState((state) => {
        const updatedState = doSomethingWithState(state);
        return state;
      })
    }
    

    这是关于使用函数vs setState的一篇很棒的文章,还包括一个演示问题的codepen示例 . https://medium.com/@shopsifter/using-a-function-in-setstate-instead-of-an-object-1f5cfd6e55d1#.gm2t01g70

相关问题