自動(dòng)批量更新
在React18之前,React 只會(huì)在事件處理程序中進(jìn)行批量更新大磺。在Promise,setTimeout及本地事件處理程序中抡句,在React18之前 ,是不會(huì)進(jìn)行批量更新的杠愧。
但在React18中待榔,在concurrent模式中,無(wú)論更新來(lái)自哪里流济,都會(huì)進(jìn)行批量處理锐锣。
如果不想進(jìn)行批量更新,在18中绳瘟,也有相應(yīng)的api提供支持:flushSync
SSR 支持Suspense
- 繼續(xù)支持renderToString,部分支持Suspense的功能
- 棄用了renderTONodeStream雕憔,
- 啟用新apipipeToNodeWritable,完全支持Suspense功能
Suspense 機(jī)制更新
暫且稱(chēng)18以前的Suspense 為L(zhǎng)egacy Suspense,
18以后的為Concurrent Suspense
下面是一個(gè)相關(guān)的場(chǎng)景說(shuō)明:
const refChild = useRef ( null )
<Suspense fallback={<Loading />}>
<Parent />
<Child ref={refChild}/>
</Suspense>
在17中,Child 組件會(huì)掛載到DOM上糖声,并觸發(fā)相關(guān)的副作用或生命周期
在18 中斤彼,Child組件不會(huì)掛載到DOM上,其副作用蘸泻、生命周期也不會(huì)再Parent解決阻塞之前觸發(fā)
在 17中琉苇,refChild.current在Parent 解決之前,將在初始渲染時(shí)立即指向 DOM 節(jié)點(diǎn)悦施。
在18中并扇,refChild.current在 Parent 解決并且 Suspense 邊界未阻塞之前將為 null。
在這里的話抡诞,在升級(jí)的時(shí)候穷蛹,對(duì)于以前涉及的相關(guān)代碼,可能需要注意一下昼汗。
Concurrent模式及其功能
在Concurrent模式下 肴熏,正式支持:
- useTransition
- useDeferredValue
- SuspensList
useTransition
useTransition
場(chǎng)景:
存在tab A 和 tab B ,用戶目前在A乔遮,點(diǎn)擊跳轉(zhuǎn) 到 B扮超。
交互路徑一:
直接跳轉(zhuǎn)到tab B,用戶在loading階段等待。tab A 不可見(jiàn)蹋肮,也無(wú)其他相應(yīng)和交互出刷,用戶體驗(yàn)不好
交互路徑二:
用戶在tab A 等待,等tab B加載完后坯辩,再跳轉(zhuǎn)到B馁龟。此時(shí)沒(méi)有一些交互反饋,用戶不知道發(fā)生了什么漆魔,用戶體驗(yàn)更差坷檩。
交互路徑三:
用戶在tab A 等待,等tab B加載完后改抡,再跳轉(zhuǎn)到B矢炼,期間有l(wèi)oading 提示 tabB 的加載情況。用戶體驗(yàn)較好阿纤。
與setTimeout區(qū)別:
useTransition不像setTimeout那樣被安排在稍后的時(shí)間句灌。它是立即執(zhí)行的。立即執(zhí)行后欠拾,被useTransition包裹的更新被當(dāng)作非緊急事件來(lái)處理胰锌,被打上transition這樣的標(biāo)志,
useDeferredValue
這讓我們可以立即顯示 input 的新文本藐窄,從而感覺(jué)到網(wǎng)頁(yè)的響應(yīng)资昧。同時(shí),MySlowList “延后” 幾秒荆忍,根據(jù) timeoutMs 格带,更新之前,允許它在后臺(tái)渲染當(dāng)前文本刹枉。
與 Transition 機(jī)制類(lèi)似践惑,相當(dāng)于延遲狀態(tài)更新,在新數(shù)據(jù)準(zhǔn)備好之前嘶卧,可以繼續(xù)沿用舊數(shù)據(jù)尔觉,如果 1 秒內(nèi)新數(shù)據(jù)來(lái)了,(從舊內(nèi)容切換到)顯示新內(nèi)容芥吟,否則立即更新?tīng)顟B(tài)侦铜,該 loading 就 loading
與 Transition 的區(qū)別在于,useDeferredValue是面向狀態(tài)值的钟鸵,而 Transition 面向狀態(tài)更新操作钉稍,算是 API 及語(yǔ)義上的差異,機(jī)制上二者非常相像
SuspensList
提供SuspenseList 來(lái)控制 Suspense內(nèi)容的渲染順序棺耍,來(lái)保證列表中元素的顯示順序按相對(duì)位置來(lái)贡未,來(lái)避免內(nèi)容被擠下去。
在1中:如果你持續(xù)的刷新,你會(huì)發(fā)現(xiàn)有的時(shí)候文章列表會(huì)先到達(dá)俊卤,有的時(shí)候“趣聞”會(huì)先到達(dá)
在2中:現(xiàn)在我們總是要等待這兩個(gè)數(shù)據(jù)都獲取到之后嫩挤,如果其中一個(gè)先到達(dá)到,還需要等待另一個(gè)
在3中:這個(gè) revealOrder="forwards" 配置表示這個(gè)列表中最接近的 <Suspense> 只會(huì)根據(jù)在樹(shù)中的顯示順序來(lái)“展開(kāi)”它們的內(nèi)容 — 即使它們的數(shù)據(jù)在不同的順序到達(dá)消恍。