react 關於this.setState使用時,第一次沒法獲取數據,第二次獲取的數據是第一次觸發的疑問

我使用的是antd組件,html

compareClickFn(orderCodes, fileNames) {
    printLog("orderCodes----------"+ orderCodes); printLog("fileNames----------"+ fileNames); this.setState({ show: !this.state.show, orderCode: orderCodes, fileName: fileNames, }); printLog("orderCode and fileName------"+ this.state.show + "----" + this.state.fileName); const ShowAnim = document.getElementById('ShowAnim'); if (this.state.show === false) { ShowAnim.style.display = 'block'; this.state.type = 'primary'; } else { ShowAnim.style.display = 'none'; this.state.type = 'ghost'; } }

這段代碼是<Button>組件的onclick事件函數,其中orderCoder和fileName已經獲取到了,我想要將這些值保存進入this.state中對應的變量裏,可是在觸發事件時,出現了第一次點擊的時候並無將數據傳遞進去,在第二次點擊的時候將第一次的數據傳遞進去了,這個問題該如何解決?react

 

4個回答

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; /* MobX managed instance state */ constructor(props, context) { super(props, context) this.selection = props.values[0] } //...

上面代碼取自這篇文章的裏: 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

和 antd 不要緊。

setState 是異步的:https://facebook.github.io/re...

0

在setState回調裏寫要作的事情

 

引用原文:https://segmentfault.com/q/1010000007343714

 

寫博客是爲了記住本身容易忘記的東西,另外也是對本身工做的總結,文章能夠轉載,無需版權。但願盡本身的努力,作到更好,你們一塊兒努力進步!

若是有什麼問題,歡迎你們一塊兒探討,代碼若有問題,歡迎各位大神指正!

相關文章
相關標籤/搜索