其实setState本身是同步的,因为在react合成事件和生命周期中使用,会被添加到react的更新队伍中,所以看起来是异步而已。
所以才有了setTimeout事件,原生事件,promise情况下是同步,在react生命周期和合成事件是异步。
来看很常见的demo
import { useEffect, useState } from 'react';
const App = () =>{
console.log('app~~~')
useEffect(() => {
console.log('useEffect~~~~')
})
const [value,setValue] = useState(100)
const handleClick=()=>{
setValue(value+1)
setValue(value+2)
console.log('value1 ', value)
setValue((value)=>value+3)
setValue((value)=>value+4)
console.log('value2 ', value)
}
return (
<>
<div>{value}</div>
<button onClick={handleClick}>increase</button>
</>
)
}
export default App
输出是:
分析: 为什么app~~~和useEffect~~~会输出两次,是因为react18在组件渲染时,为了更早的验证组件完整的生命周期。
第11行,第12行,第13行,第16行:拿的都是原来的value:100, 但是到了14行,使用了函数,能拿到最新的value,所以第14行的value是102+3, 第15行的value就是105+4, 所以最后输出109。
11:100+1
12:100+2
14:100+2+3
15:100+2+3+4