Open kangyana opened 2 years ago
react 事件中,setState 是异步更新的。 但是在 setTimeout 、addEventListener 添加的原生事件中,setState 则是同步的。
setState
setTimeout
addEventListener
// Legacy同步模式 const container = document.getElementById('root'); ReactDOM.render(<App />, container);
setState 的更新统一是异步的。
// Concurrent异步模式,在这个模式下,任何情况下setState都是异步更新的。目前createRoot方法还在实验中 const container = document.getElementById('root'); ReactDOM.createRoot(container).render(<App />)
在 React 18 之前,如果在回调函数的异步调用中,执行 setState,由于丢失上下文,无法做合并处理。 所以每次 setState 调用都会触发一次 重新渲染。
function handleClick() { // React 18 之前的版本 (/*...*/).then(() => { setCount(c => c + 1); // 立刻重新渲染 setShow(show => !show); // 立刻重新渲染 }); }
React 18中,任何情况下都可以合并渲染! 如果仍然希望setState之后立即重新渲染,只需要使用 flushSync 包裹。
flushSync
function handleClick() { // React 18 fecth(/*...*/).then(() => { ReactDOM.flushSync(() => { setCount(c => c + 1); // 立刻重新渲染 setFlag(f => !f); }) }) }
1. setState 同步更新还是异步更新?
React18 以前的版本
react 事件中,
setState
是异步更新的。 但是在setTimeout
、addEventListener
添加的原生事件中,setState
则是同步的。React18 以后
setState
的更新统一是异步的。2. setState 批更新
在 React 18 之前,如果在回调函数的异步调用中,执行
setState
,由于丢失上下文,无法做合并处理。 所以每次setState
调用都会触发一次 重新渲染。React 18中,任何情况下都可以合并渲染! 如果仍然希望setState之后立即重新渲染,只需要使用
flushSync
包裹。