【问题标题】:setTimeout in react setState反应setState中的setTimeout
【发布时间】:2023-03-16 04:56:01
【问题描述】:
this.setState(prevState => ({
    score:            prevState.score + 10,
    rightAnswers:     prevState.rightAnswers + 1,
    currentQuestion:  setTimeout(() => {
      prevState.currentQuestion + 1
    }, 2000)
    }))
  }

点击按钮我改变了状态。我的目标是延迟 currentQuestion 状态更改,在此期间我想显示某些状态消息,但我想立即更新分数而不会延迟。

这样做的正确方法是什么?

PS:这个变体不起作用,它是为了整体表示我想做的事情。

谢谢。

【问题讨论】:

  • setTimeout in setState 不仅在语法上而且在概念上都是错误的:如果您想在指定的时间后再次更改状态,然后再调用@ 987654325@ 内setTimeout。一个随机的例子:medium.com/@machadogj/…
  • 你是对的,谢谢。我最初认为应该有 2 个 setStates,但希望也许我可以只用 1 个

标签: javascript reactjs settimeout setstate timedelay


【解决方案1】:

您可以通过多种方式做到这一点:

1) 拨打两个电话到setState。 React 会将所有对 setState 的并发调用批处理到一个批处理更新中,所以这样的事情非常好:

this.setState( prevState => ({
  score: prevState.score + 10,
  rightAnswers: prevState.rightAnswers + 1
}));

setTimeout( () => {
  this.setState( prevState => ({
    currentQuestion: prevState.currentQuestion + 1
  }));
}, 2000);

2) 您可以使用setState 回调来更新状态您的第一次通话结束后:

this.setState(prevState => ({
  score:            prevState.score + 10,
  rightAnswers:     prevState.rightAnswers + 1
}), () => {
  setTimeout( () => {
      this.setState( prevState => ({
      currentQuestion: prevState.currentQuestion + 1
    }));
  }, 2000);
});

【讨论】:

  • 在您的第一个示例中,您确定 React 会批处理在第一个示例后两秒超时发生的 setState 吗?
  • 不,可能不会,因为 2 秒是组件重新渲染的充足时间。只是提供有关 setState 工作原理的更多背景信息。
  • 所以澄清一下 - 在回调的情况下,setState react 将执行一批更新,对吧?
  • @Proopy 通常,但在您的情况下,2 秒的延迟可能会导致它不会与第一次调用一起批处理。
【解决方案2】:

首先使用setState 将分数和问题更改为null 之类的值,以便您知道它的更新,然后再设置超时。

class Example extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      score: 1,
      question: "A"
    }
  }

  update() {
    this.setState(prev => ({
      score: prev.score + 1,
      question: null
    }));

    this.change = setTimeout(() => {
      this.setState({question: "B"})
    }, 2000)
  }

  render() {
    let {score, question} = this.state;
    let style = {border: "1px solid black"}
	
    return (
      <div style={style} onClick={this.update.bind(this)}>
        <div>{score}</div>
        <div>{question ? question : "Loading..."}</div>
      </div>
    )
  }
}

ReactDOM.render( < Example / > , document.querySelector("#app"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

【讨论】:

    猜你喜欢
    • 2020-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-12
    • 1970-01-01
    • 1970-01-01
    • 2021-06-02
    • 2018-09-25
    相关资源
    最近更新 更多