React18?useState何時(shí)執(zhí)行更新及微任務(wù)理解
函數(shù)式組件中的useState
前言:眾所周知useState是異步的,但網(wǎng)絡(luò)上對于useState何時(shí)異步更新并沒有一個(gè)共識,為了探究,做一個(gè)簡單的實(shí)驗(yàn),實(shí)驗(yàn)?zāi)康氖翘骄縰seState與微任務(wù)、宏任務(wù)的先后關(guān)系
測試1
實(shí)驗(yàn)步驟:點(diǎn)擊按鈕觸發(fā)事件,在事件中我們做三件事:修改state/定義一個(gè)宏任務(wù)setTimeout /定義一個(gè)微任務(wù)promise.then ,我們在微任務(wù)中打上debugger,暫停代碼,觀察此時(shí)頁面是否更新了數(shù)據(jù)。
實(shí)驗(yàn)代碼
import React, { useState } from 'react'
export default function Test() {
const [msg, setMsg] = useState('我是初始值')
const onChange = () => {
setMsg('我是更新值')
setTimeout(() => {
console.log('宏任務(wù)')
}, 0);
Promise.resolve().then(res=>{
debugger
console.log('微任務(wù)')
})
}
return (
<div>
<h2>{msg}</h2>
<button onClick={onChange}>按鈕</button>
</div>
)
}
實(shí)驗(yàn)期望:
- 如果頁面更新了,則說明在微任務(wù)之前,useState就已經(jīng)更新了狀態(tài),并且頁面渲染完畢了
- 如果頁面未更新,則說明微任務(wù)在useState更新之前
實(shí)驗(yàn)結(jié)果

結(jié)果分析 結(jié)果符合第一種期望,useState在此微任務(wù)之前就完成了,由此得出useState異步更新是在微任務(wù)之前,同步代碼之后的結(jié)果,這是不準(zhǔn)確的。讓我們進(jìn)一步測試。
測試2
實(shí)驗(yàn)步驟:測試2在廁所1上調(diào)整下順序。定義宏任務(wù)/定義微任務(wù)/修改state
實(shí)驗(yàn)代碼:
import React, { useState } from 'react'
export default function Test() {
const [msg, setMsg] = useState('我是初始值')
const onChange = () => {
setTimeout(() => {
console.log('宏任務(wù)')
}, 0);
Promise.resolve().then(res=>{
debugger
console.log('微任務(wù)')
})
setMsg('我是更新值')
}
return (
<div>
<h2>{msg}</h2>
<button onClick={onChange}>按鈕</button>
</div>
)
}
實(shí)驗(yàn)期望
- 如果頁面更新了,則說明在微任務(wù)之前,useState就已經(jīng)更新了狀態(tài),并且頁面渲染完畢了
- 如果頁面未更新,則說明微任務(wù)在useState更新之前
實(shí)驗(yàn)結(jié)果

結(jié)果分析
微任務(wù)已經(jīng)執(zhí)行了,但是頁面還未更新,說明useState并不一定是在微任務(wù)之前執(zhí)行。具體的執(zhí)行結(jié)果與代碼定義順序有關(guān)。
類組件中的setState
setState在promise之前定義
export default class Test extends React.Component {
state = {
msg: '我是初始值'
}
handleClick = ()=>{
setTimeout(() => {
console.log('宏任務(wù)')
}, 0);
this.setState({
msg: '我是更新值'
},()=>{
console.log('更新了msg:', this.state.msg)
})
Promise.resolve().then(() => {
console.log('微任務(wù)觸發(fā)msg:', this.state.msg)
})
}
render() {
return (
<div>
<h2>{this.state.msg}</h2>
<button onClick={this.handleClick}>按鈕</button>
</div>
)
}
}
執(zhí)行結(jié)果:

結(jié)果說明:當(dāng)先調(diào)用setState,后定義promise時(shí),setState會在微任務(wù)之前更新狀態(tài)。
setState在promise之后定義
export default class Test extends React.Component {
state = {
msg: '我是初始值'
}
handleClick = ()=>{
setTimeout(() => {
console.log('宏任務(wù)')
}, 0);
Promise.resolve().then(() => {
console.log('微任務(wù)觸發(fā)msg:', this.state.msg)
})
this.setState({
msg: '我是更新值'
}, () => {
console.log('更新了msg:', this.state.msg)
})
}
render() {
return (
<div>
<h2>{this.state.msg}</h2>
<button onClick={this.handleClick}>按鈕</button>
</div>
)
}
}
實(shí)驗(yàn)結(jié)果:

結(jié)果說明:當(dāng)先定義promise,后調(diào)用setState時(shí),setState會在微任務(wù)之后更新狀態(tài)。
結(jié)論
useState/setState的異步并不是一種在同步之后,微任務(wù)之前的特殊情況,而是一種和微任務(wù)相同的機(jī)制,看見簡單理解為微任務(wù),因?yàn)樗母聲r(shí)機(jī)與微任務(wù)的調(diào)用相同,但react是不是用微任務(wù)來實(shí)現(xiàn)的更新,我不能確定。
以上就是React18 useState何時(shí)執(zhí)行更新及微任務(wù)理解的詳細(xì)內(nèi)容,更多關(guān)于React18 useState執(zhí)行更新的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
React實(shí)現(xiàn)浮層組件的思路與方法詳解
React?浮層組件(也稱為彈出組件或彈窗組件)通常是指在用戶界面上浮動顯示的組件,本文主要介紹了浮層組件的實(shí)現(xiàn)方法,感興趣的小伙伴可以了解下2024-02-02
react redux中如何獲取store數(shù)據(jù)并將數(shù)據(jù)渲染出來
這篇文章主要介紹了react redux中如何獲取store數(shù)據(jù)并將數(shù)據(jù)渲染出來,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08
react native實(shí)現(xiàn)監(jiān)控手勢上下拉動效果
這篇文章主要為大家詳細(xì)介紹了react native實(shí)現(xiàn)監(jiān)控手勢上下拉動效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-05-05

