由于setState是异步的,它是否通过回调队列执行?

时间:2019-08-30 06:26:03

标签: javascript reactjs

我是React的新手,对setState在幕后的工作方式有所了解。因此,我想问一些问题。首先,setState是否总是异步的?如果不是在一般情况下是同步的。其次,它是如何通过Web API执行然后在回调队列中在setState中发生异步的?伙计们,如果有不清楚的地方,请告诉我。我真的很需要您的帮助。

3 个答案:

答案 0 :(得分:4)

是的。它总是异步的,从不同步。 开发人员常见的错误是这样的

 handleEvent(newValue) {
   this.setState({ value: newValue }, () => {
      // you can get the updated state here
      console.log(this.state.value)
   })
   this.doSomething(newValue)
 }

 doSomething(newValue) {
   // this.state.value is still the old value
   if (this.state.value === newValue) {
      // blabla
   }
 }

您无法确定状态更新需要花费多少时间。

答案 1 :(得分:1)

是的。它是异步的。在Javascript中,异步操作是使用event loop

处理的

https://www.youtube.com/watch?v=8aGhZQkoFbQ

答案 2 :(得分:1)

反应setState并不总是异步的,它取决于如何触发状态更改。

1)同步-如果操作在Reactjs世界之外,或者状态更改是由计时器用户诱发的 事件处理程序触发的,则reactjs无法批量更新,因此必须立即更改状态。

2)异步 如果状态更改是由onClick触发的,那么Reactjs可以批量更新状态,以提高性能。

工作codesandbox link

Reference post

router.post('/signup', (req, res) => {
    if (req.body.password !== req.body.confirmPassword) {
        // return error i.e return res.status(400).send('Password mismatch')
    }
    // do the signup and return your response i.e res.status(201).send(user);
});
  

控制台日志

import React from "react";
import ReactDOM from "react-dom";

import "./styles.css";

class App extends React.Component {
  state = {
    counter: 0
  };
  componentDidMount() {
    // const intervalId = setInterval(this.updateState, 5000);
    // this.setState({intervalId: intervalId});
    this.counter.addEventListener("mousedown", this.updateState);
  }
  componentWillUnmount() {
    this.counter.removeEventListener("mousedown", this.updateState);
    // clearInterval(this.state.intervalId);
  }
  updateState = event => {
    console.log("= = = = = = = = = = = =");
    console.log("EVENT:", event ? event.type : "timer");
    console.log("Pre-setState:", this.state.counter);
    this.setState({
      counter: this.state.counter + 1
    });
    console.log("Post-setState:", this.state.counter);
  };
  render() {
    return (
      <div className="App">
        <span onClick={this.updateState} ref={elem => (this.counter = elem)}>
          Counter at {this.state.counter}
        </span>
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

正如您在控制台日志中看到的那样, = = = = = = = = = = = = EVENT: mousedown Pre-setState: 0 Post-setState: 1 = = = = = = = = = = = = EVENT: click Pre-setState: 1 Post-setState: 1 事件状态更改会立即反映出来,但是mousedown更改是异步的,或者说是更好的批处理。

因此更好地假设状态更改将是异步的,并使用回调处理程序来避免错误。 当然,回调内的所有内容都将通过javascript中的事件循环进行处理。

希望有帮助!