0
已採納
setState其實並非異步的,它在整個執行過程當中沒有任何的setTimeout或者promise等異步操做。git
你能夠嘗試下在setTimeout(或者本身綁定的DOM事件,可是不要在JSX中綁定事件哦,要本身手動addEventListener,目的就是擺脫React的控制
)中調用setState(newState)方法,而後緊接着log看下你設置的新的state有沒有起做用呢?若是再仔細一些,你還能夠研究下此次的setState、render、log的執行順序是怎樣的呢?github
不要被setState的名字欺騙了,它實際上是 set pending state
—— 將你傳入的newState放入一個待更新的隊列,到此爲止你的setState方法基本已經完成了它全部的工做。算法
真正執行state合併更新的另有其人 —— transaction
,對於React的transaction網上有相應的講解,在這裏再也不贅述,有興趣能夠看下Transaction源碼以及ReactUpdates源碼segmentfault
setTimeout中setState和在生命週期裏setState的區別在於,setTimeout中的setState會本身觸發一個transaction,而生命週期中的setState已經處於React生命週期的transaction中了。promise
最後:若是想在newState起效後執行一些處理,最好仍是放在setState的回調中哦antd
2
this.setState是異步的,因此你一呼叫this.setState完,立刻做獲取this.state中的值,不必定能獲取獲得改變的值。異步
1. 用this.setState的第二參數,給一個回調來在更新後執行,例如:
this.setState({ something: true }, () => console.log(this.state))
2. 用componentDidUpdate()
這個生命週期方法,把肯定更新後要做的代碼放裏面。
3. mobx有神奇的@observer
與@observable
能夠做這事。
@observer class Select extends React.Component { @observable selection = null;
上面代碼取自這篇文章的裏: https://medium.com/@mweststra...async
如下是補充"爲什麼說setState是異步的?"的回答
setState
並不是使用setTimeout或promise的那種進入到事件迴圈(Event loop)的異步執行,但它的執行行爲在React庫中控制時,的確是異步的。以最精確的說法來講,"它不是保證同步的",官方的說明也是如此。
setState
包含在其中執行過程是一個很複雜的過程,從最初的版本到如今,也有無數次的修改。它的工做除了要設定this.state
以外,還要負責觸發重渲染,這裏面須要通過React核心中演算法,也就是virtual DOM的演算,最終才能決定是否要進行重渲染,以及如何渲染。爲了批次與效能的理由,多個setState呼叫有可能在過程當中要進行合併,因此它被設計以異步來執行是合理的,但這主要限於在React庫的控制之中。
那麼setState會在什麼時候以同步的方式來執行,也就是當即更動this.state
?答案是在React函式庫控制以外時,它就會以同步的方式來執行,在下面兩篇文章中,都有相似的例子:
但大部份的使用狀況下,咱們都是使用了React庫中的表單控件,例如select, button,這些是React庫中人造的控件與事件,是處於React庫的控制之下,setState
就會以異步的方式執行。因此通常來講,咱們會認爲setState
就是異步執行,並非用源代碼來看說它是否是有使用setTimeout或Promise之類的方式轉爲JS的異步執行方式,而是以它在React庫的控制之下,以執行行爲與順序來理解。
如下是翻譯自官方setState源碼的註解,其實若是是官網的說明也是相似的說明:
不保證this.state
會當即更新,因此在調用這個方法後存取this.state
可能會回傳舊的值。
不保證調用setState
就會同步地執行,而它們也可能最終被被批量調用(屢次調用的狀況下)。你能夠提供額外的回調,回調將會在setState
實際被完成時被執行。
0
0