React狀態更新是異步的,爲了性能優化,狀態更新都是批量更新的。
可是否能夠確認 setState 調用後狀態的更新順序呢?
考慮如下按鈕點擊的例子:
是否有可能 a 是 false,b 是 true?java
import React, { PureComponent } from 'react'; class Subclass extends PureComponent { state = { a: true, b: true } handleClick = () => { this.setState({ a: false, b: false }); } render() { return <button onClick={this.handleClick}>Click</button> } }
是否有可能 a 是 false,b 是 true?react
class Parent extends PureComponent { state = { a: false } render() { return <Sub setParentState={this.setState.bind(this)}/> } } class Sub extends PureComponent { state = { b: false } handleClick = () => { this.props.setParentState({ a: true }); this.setState({ b: true }); } render() { return <button onClick={this.handleClick}>Click</button> } }
Dan Abramov 先給出告終論:git
同一個組件中,setState 是否有肯定的順序?是的。 不一樣組件中,setState 是否有肯定的順序?是的。
狀態始終是按照特定的順序更新的。不管你是否看到介於兩個狀態之間的一箇中間狀態,不管你是否在批處理內。
目前(React 16 及更早版本),默認狀況下,只有 React 事件處理程序中的更新纔會被批處理。有一個不穩定(unstable)的 API 來強制在事件處理程序以外進行批處理,以便在須要時處理罕見的狀況。
在將來的版本(多是 React 17 或更高版本)中,React 將 默認批量更新全部更新
在 React 事件處理程序中,不論 setState() 調用了多少次,也不論 setState()被多少個組件調用,它們在事件結束時只會生成一次從新渲染
在這兩個例子中,setState() 調用都發生在 React 事件處理程序中。所以,在事件結束時,他們老是被合併到一塊兒(並且你看不到中間狀態)
更新老是 按照它們發生的順序進行淺合併(shallowly merge)
在 React 16 和更早版本中,React 事件處理程序以外尚未默認的批處理。所以,若是在例子中,咱們把 handleClick 替換爲 AJAX 處理程序,那麼每一個 setState() 都會當即處理。在這種狀況下,你會看到一箇中間狀態:github
promise.then(() => { // 咱們不在事件處理程序中,所以它們都會被刷新。 this.setState({a: true}); // 使用 {a: true, b: false } 從新渲染 this.setState({b: true}); // 使用 {a: true, b: true } 從新渲染 this.props.setParentState(); // 從新渲染父組件 });
咱們認識到,_根據是否處於事件處理程序中,行爲是不一樣的,這是不方便的。這將在將來的 React 版本中進行更改,默認狀況下將批量更新全部更新(並提供選擇性 API 以同步刷新更改)。直到咱們切換默認行爲(可能在 React 17 中),有一個 API 能夠用來強制批量處理:promise
promise.then(() => { // 強制批量處理 ReactDOM.unstable_batchedUpdates(() => { this.setState({a: true}); // 不從新渲染 this.setState({b: true}); // 不從新渲染 this.props.setParentState(); // 不從新渲染 }); // 當咱們退出 unstable_batchedUpdates函數後,從新渲染一次 });
在 React 內部,事件處理程序都被包裝在 unstable_batchedUpdates 內,這就是默認狀況下批處理的緣由。請注意,將 setState 封裝 unstable_batchedUpdates 兩次是不起做用的。當咱們退出最外層的unstable_batchedUpdates 調用時,更新被刷新。
原文: React 是否保持 state 更新的順序?性能優化