繁体   English   中英

即使使用正确的格式,React setState 也不等待

[英]React setState Not Waiting Even With Proper Format

这是在React中调用 setState 的推荐方式

this.setState((state, props) => ({
  counter: state.counter + props.increment
}));

但是,这种格式在转到此代码中的下一行之前仍然不会等待 setState 完成:

  pressed = () => {
    this.setState((prevState, props) => ({
      token: 1
    }), () => console.warn("TOKEN setState Callback: " + this.state.token));
    console.warn("TOKEN before timeout: " + this.state.token);
    setTimeout(function() {console.warn("TOKEN after timeout: " + this.state.token)}.bind(this), 500);
    ...
    //rest of function
  }

在这种情况下,这是输出的顺序
1. TOKEN setState 回调:1
2. 超时前TOKEN:0
3. 超时后令牌: 0 。

我不想把//rest of my function放在回调中,因为它是一个很长的函数。 使函数“异步”并在this.setState前面加上await有效,但不建议在各种来源上使用。

为什么我的代码不起作用? 如何在超时之前调用 TOKEN 之前完成 setState 调用,而不会大量更改我的代码?

谢谢。

提供回调函数不会导致 setState 变得同步。 相反,你应该把你的代码放在回调函数中,一旦设置状态完成,它就会被调用。

    this.setState((prevState, props) => ({
      token: 1
    }), () => {
      console.warn("TOKEN setState Callback: " + this.state.token);
      console.warn("TOKEN before timeout: " + this.state.token);
      setTimeout(function() {console.warn("TOKEN after timeout: " + this.state.token)}.bind(this), 500);
      //rest of function
    });

我不想把我的函数的其余部分放在回调中,因为它是一个很长的函数。

如果您希望代码在设置状态后运行,则将其放入回调中。 如果这样更易于阅读,您可以将其提取到辅助方法中,但是您的代码长度不会改变您需要调用它的位置。

您的另一个选择是将代码放在 componentDidUpdate 中,并将其包装在检查中以查看令牌是否已更改:

componentDidUpdate(prevProps, prevState) {
  if (prevState.token !== this.state.token) {
      console.warn("TOKEN before timeout: " + this.state.token);
      setTimeout(function() {console.warn("TOKEN after timeout: " + this.state.token)}.bind(this), 500);
      //rest of function
  }
}

使函数“异步”并在 this.setState 前面加上 await 有效,但不建议在各种来源上使用。

不推荐的原因是它依赖于 react 的实现细节。 它们碰巧以这样一种方式实现了 setState 的批处理,如果您将一个微任务排队,您将等待足够长的时间让 react 完成其工作。 但是 React 并不能保证这是他们实现它的方式。

从文档

将 setState() 视为更新组件的请求而不是立即命令。 为了获得更好的感知性能,React 可能会延迟它,然后一次更新多个组件。 React 不保证状态更改会立即应用。

因此,即使您已运行 setState,它也不会自动更新令牌以供您在函数中使用新值。 如果令牌仅在该令牌内使用,那么我将在内部设置一个变量来增加令牌并在您的函数内专门使用它,然后最后使用this.setState({token: 1})设置您的状态

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM