直接主題,開始前先看一段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...