簡體   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