react非同步setState簡單實現

2021-10-02 23:45:32 字數 2943 閱讀 4573

直接主題,開始前先看一段demo:

class demo;

} componentdidmount() )

// this.setstate(() =>

// })

// this.setstate((prevstate) =>

// })

// console.log(this.state.count) // 0 * 10

}} render()

);}}

在平常使用react的過程中,關於setstate的使用有上面幾種方式,那麼他們的輸出結果又有什麼不一樣?

熟悉的同學可以馬上給出答案,分別是1, 1, 10

至於為什麼,我們可以通過一段簡單示例來了解下 setstate 的過程。

我們常說 setstate 是非同步的,但實際上 setstate 本身只是個同步函式,只是內部處理邏輯導致我們看到的結果是『非同步』的,這也是為什麼當我們使用 console 去列印剛 setstate 完的資料卻發現沒有變化的原因。當setsate不在react控制下的時候,setstate就會同步更新state了,比如當用settimeout包裹setstate的時候。

我們都知道setstate為元件自帶方法,而我們建立class元件的時候會繼承react的component,所以我們先模擬乙個component,以及函式setstate,這個函式接受乙個引數state,這個引數可以是物件也可以是方法,然後函式內部呼叫了乙個state處理函式我們給它叫做setstatequeue,這個函式接受statechange以及當前元件

class component ) 

}setstate(state)

}function setstatequeue(statechange, comp)

setstate方法通過乙個佇列機制實現state更新,我們需要定義個變數queue去儲存這些更新, 這裡我們還多加了個變數componentrenderqueue記錄更新的元件

const queue = 

const componentrenderqueue =

那麼如何實現setstate的非同步呢?說到非同步那就很容易想到settimeout跟promise

那麼我們可以這麼做,至於為什麼可以了解下js的事件執行(event loop)。當當前更新隊列為空的時候,延遲更新flush

function defer(fn)  else , 0)

}}function setstatequeue(statechange, component)

}

每次執行setstate()的時候,先將加入更新佇列, 同時記錄對應的元件

function setstatequeue(statechange, component) 

queue.push()

let componentexist = componentrenderqueue.some(item => )

if(!componentexist)

}

前面的setstate操作都結束了,那麼就要開始真正的結果處理了. 依次執行更新佇列中更新操作並記錄,同時需要對上次的結果進行記錄。當全都處理完成之後,對元件的state進行更新。具體邏輯如下:

function flush() 

while(item) = item

const componentname = component.constructor.name

if(!component.prevstate) , component.state)

}const newstate = typeof statechange === 'function' ? statechange(component.prevstate, component.props) : statechange

updater[componentname] =

component.prevstate = newstate

item = queue.shift()

}for(let u in updater)

while (comp)

}

const queue =  

const componentrenderqueue =

function defer(fn) else , 0)

}}function setstatequeue(statechange, component)

queue.push()

let componentexist = componentrenderqueue.some(item => )

if(!componentexist)

}// 更新state

function flush()

while(item) = item

const componentname = component.constructor.name

if(!component.prevstate) , component.state)

}const newstate = typeof statechange === 'function' ? statechange(component.prevstate, component.props) : statechange

updater[componentname] =

component.prevstate = newstate

item = queue.shift()

}for(let u in updater)

while (comp)

}

React中setState為非同步機制

setstate用來更改state,並觸發render方法重新渲染頁面,這之間要經過react核心中diff演演算法比較dom樹,最終決定是否需要被渲染如何渲染。如何在第一時間獲取並應用setstate的值,set完第一時間呼叫方法即可獲取 如 this.setstate nowstate 便利 1...

react中setState同步 非同步問題

class example extends react.component componentdidmount console.log this.state.val 第 1 次 log this.setstate console.log this.state.val 第 2 次 log settim...

react中state與setstate的使用

我們可以利用state來定義一些變數的初始值 放在construcor裡 this.state 要更改state裡的值,注意要遵循react裡immutable規範,state不允許我們做任何改變,只能通過setstate來更改 const list this state.list list.spl...