解讀react的setSate的異步問題

在咱們閱讀文檔的時候,大多都說react的setState是異步的,但是它真的是異步的嗎?若是是,那咱們還能夠猜測:那能夠不能夠同步?那何時須要異步,何時須要同步呢?

咱們先來看下react的官方對setSate的說明:react

將setState()認爲是一次請求而不是一次當即執行更新組件的命令。爲了更爲可觀的性能,React可能會推遲它,稍後會一次性更新這些組件。React不會保證在setState以後,可以馬上拿到改變的結果。

一個很經典的例子:異步

// 初始state.count 當前爲 0
componentDidMount(){
    this.setState({count: state.count + 1});
    console.log(this.state.count)
}

若是你熟悉react,你必定知道最後的輸出結果是0,而不是1。性能

咱們再來看一個例子學習

class Demo extends Component {
  constructor(props) {
    super(props);
    this.state = { number: 0 };
  }
  render() {
    return <button ref="button" onClick={this.onClick.bind(this)}>點我</button>;
  }
  componentDidMount() {
    //手動綁定mousedown事件
    this.refs.button.addEventListener(
      "mousedown",
      this.onClick.bind(this)
    );
   
    //setTimeOut
    setTimeout(this.onClick.bind(this), 1000);
  }
  onClick(event) {
    if (event) {
      console.log(event.type);
    } else {
      console.log("timeout");
    }
    console.log("prev state:", this.state.number);
    this.setState({
      number: this.state.number + 1
    });
    console.log("next state:", this.state.number);
  }
}
export {Demo};

在這個組件中採用3中方法更新statethis

1.在div節點中綁定onClick事件
 2.在componentDidMount中手動綁定mousedown事件
 3.在componentDidMount中使用setTimeout調用onClick

在點擊組件後,你能夠猜到結果嗎?輸出結果是:code

timeout
prev state: 0
next state: 1
mousedown
prev state: 1
next state: 2
click
prev state: 2
next state: 2

結果彷佛有點出人意料,三種方式只有在div上綁定的onClick事件輸出了能夠證實setState是異步的結果,另外兩種方式顯示setState彷佛是同步的。component

總結:
1.在組件生命週期中或者react事件綁定中,setState是經過異步更新的。
2.在延時的回調或者原生事件綁定的回調中調用setState不必定是異步的。生命週期

這個結果並不說明setState異步執行的說法是錯誤的,更加準確的說法應該是setState不能保證同步執行。事件

我的學習總結,有錯誤的地方歡迎指正٩̋(๑˃́ꇴ˂̀๑)
相關文章
相關標籤/搜索