React 中的 setState 回撥函式

Irakli Tchigladze 2023年1月30日 2021年12月4日
  1. 為什麼需要回撥引數
  2. 何時使用 setState() 回撥函式
React 中的 setState 回撥函式

乍一看,React 元件的 .setState() 方法似乎很簡單。它更新現有狀態以反映引數的變化。然而,很多人不知道 .setState() 方法還接受另一個可選引數。這個引數是一個回撥函式,在狀態更新後立即執行。

為了編寫更可靠的程式碼,你需要了解 .setState() 回撥函式的作用以及如何使用它。

為什麼需要回撥引數

大多數 React 開發人員不知道 .setState() 方法是非同步的。更新不會立即發生。如果你嘗試在呼叫 setState() 後立即讀取 state 的更新內容,你可能會失敗或讀取錯誤的資料。

為了解決這個問題,setState() 方法採用另一個可選引數 - 回撥函式。只有在狀態更新後才會執行回撥函式中指定的操作。

何時使用 setState() 回撥函式

正如我們上面提到的,setState 呼叫是非同步的。它不會立即更新狀態物件。如果你想根據最近的更新執行檢查或其他一些操作,使用 setState() 回撥是一個很好的做法。但是,這不是執行此類操作的唯一方法。我們將在後面的部分討論替代方案。

setState() 回撥對於以下型別的操作非常有用:呼叫 API、檢查 state 的內容以有條件地丟擲錯誤,以及需要在 state 更新後立即執行的其他操作. setState() 回撥也經常用於驗證。

例如,如果我們想使用 <input> 來更新狀態,我們可以使用回撥函式絕對確定地讀取更新後的值。如果沒有回撥,我們可能會檢查狀態的陳舊舊版本。

程式碼示例:

class App extends Component {
  constructor(props){
    super(props)
    this.state = {
      text: ""
    }
  }
  render() {
    return (
    <div>
    	<h1>Hello World</h1>
   		<input type="text" 
         onChange={(e) => this.setState({text: e.target.value}, 
         () => console.log(this.state.text))}></input>
    </div>
    )
  }
}

回撥函式 vs render()

懷疑論者可能會問,當我可以訪問 render() 方法主體中更新的 state 時,為什麼我需要 setState() 回撥?

不同之處在於,render() 方法將在每次 state 更新時執行,而 setState() 回撥只會在更新 state 中的特定值後執行。

async 函式中的 .setState()

有時 .setState() 方法可以在非同步函式中呼叫。在這種情況下,狀態不會立即更新。

如果你使用 this 關鍵字讀取 state 屬性的值,你將獲得一箇舊值。另一方面,一旦 async 任務完成,就會呼叫回撥函式。

替代方案

React 文件建議開發人員改用 componentDidUpdate() 生命週期方法,該方法僅適用於類元件。

對於功能元件,useEffect() 可以有效地替換所有生命週期鉤子,包括 componentDidUpdate()。你只需要自定義依賴項陣列。

例如,如果你的狀態有一個 age 屬性,並且你想在狀態更新後檢查它的值,useEffect() 鉤子將如下所示:

useEffect(()=>console.log(`doing something with ${this.state.age}`), [age])
Irakli Tchigladze avatar Irakli Tchigladze avatar

Irakli is a writer who loves computers and helping people solve their technical problems. He lives in Georgia and enjoys spending time with animals.

LinkedIn