一文帶你了解React中的并發(fā)機制
一、自動批處理
React 現(xiàn)在可以自動將多個狀態(tài)更新操作批量處理,以減少不必要的渲染和提高性能。這意味著,當你在一個事件處理程序中連續(xù)調(diào)用多個狀態(tài)更新函數(shù)時,React 會將它們合并為一次更新,從而減少渲染次數(shù)。
計數(shù)器
在下面這個案例中,當用戶點擊按鈕時,handleClick
函數(shù)會連續(xù)調(diào)用三次 setCount
。由于 React 的自動批處理,這三次更新會被合并為一次更新,從而減少渲染次數(shù)。
import { useState } from 'react'; function Counter() { const [count, setCount] = useState(0); const handleClick = () => { setCount(count + 1); setCount(count + 2); setCount(count + 3); }; return ( <div> <p>Count: {count}</p> <button onClick={handleClick}>Increment by 3</button> </div> ); }
二、異步渲染
React現(xiàn)在可以支持異步渲染,這意味著 React 可以在渲染過程中暫停和恢復,從而允許其他任務(如用戶輸入或動畫)優(yōu)先執(zhí)行。這有助于提高應用程序的響應性和性能。
異步數(shù)據(jù)獲取
在下面這個案例中,AsyncComponent
組件在掛載時會異步獲取數(shù)據(jù)。由于 React 的異步渲染,當數(shù)據(jù)還未獲取到時,組件會顯示 "Loading...",而不會阻塞其他任務的執(zhí)行。
import { useState, useEffect } from 'react'; function AsyncComponent() { const [data, setData] = useState(null); useEffect(() => { fetchData().then((fetchedData) => { setData(fetchedData); }); }, []); if (data === null) { return <p>Loading...</p>; } return <div>{data}</div>; } async function fetchData() { // 模擬異步數(shù)據(jù)獲取 await new Promise((resolve) => setTimeout(resolve, 1000)); return 'Async data'; }
三、useDeferredValue:延遲值更新
useDeferredValue
是一個新的 Hook,它允許你在渲染過程中延遲某些值的更新,直到下一次渲染。這對于實現(xiàn)響應式 UI 和避免不必要的渲染非常有用。
輸入框防抖
在下面這個示例中,當用戶在輸入框中輸入文本時,useDeferredValue
會延遲更新 deferredText
,直到 500 毫秒后的下一次渲染。這有助于提高應用程序的響應性和性能。
import { useState, useDeferredValue } from 'react'; function DebounceInput() { const [text, setText] = useState(''); const deferredText = useDeferredValue(text, { timeoutMs: 500 }); const handleChange = (e) => { setText(e.target.value); }; return ( <div> <input type="text" value={text} onChange={handleChange} /> <p>Debounced value: {deferredText}</p> </div> ); }
四、useTransition:創(chuàng)建過渡狀態(tài)
useTransition
是一個新的 Hook,它允許你在狀態(tài)更新過程中創(chuàng)建一個過渡(transition),從而實現(xiàn)更細粒度的更新控制。你可以使用這個 Hook 來延遲某些狀態(tài)更新,直到過渡完成。這對于實現(xiàn)更好的用戶體驗和性能優(yōu)化非常有用。
加載狀態(tài)與過渡效果
在下面這個示例中,當用戶點擊按鈕時,handleClick
函數(shù)會使用 startTransition
創(chuàng)建一個過渡,并在過渡期間延遲更新 count
。isPending
變量表示過渡是否正在進行中,當過渡正在進行時,會顯示 "Loading..."。
import { useState, useTransition } from 'react'; function TransitionExample() { const [count, setCount] = useState(0); const [isPending, startTransition] = useTransition(); const handleClick = () => { startTransition(() => { setCount(count + 1); }); }; return ( <div> <p>Count: {count}</p> <button onClick={handleClick}>Increment</button> {isPending && <p>Loading...</p>} </div> ); }
五、Suspense 配置優(yōu)化
React新版本引入了新的 Suspense 配置選項,如 timeoutMs
和 fallbackAfterSuspense
。這些選項允許你更精細地控制 Suspense 的行為,例如設置掛起時間和在掛起后顯示備用內(nèi)容。
分頁加載與錯誤處理
在下面這個示例中,App
組件使用 Suspense
包裹了兩個異步加載的頁面組件 Page1
和 Page2
。通過設置 timeoutMs
為 1000 毫秒,我們可以在 1 秒后顯示 fallbackAfterSuspense
屬性指定的備用內(nèi)容 "Loading with suspense..."。同時,當 Page2
加載失敗時,Suspense 會捕獲錯誤并顯示默認的錯誤邊界內(nèi)容
import { Suspense } from 'react'; function App() { return ( <Suspense fallback={<div>Loading...</div>} timeoutMs={1000} fallbackAfterSuspense={<div>Loading with suspense...</div>} > <Page1 /> <Page2 /> </Suspense> ); } function Page1() { // 模擬異步數(shù)據(jù)獲取 return new Promise((resolve) => setTimeout(() => resolve(<div>Page 1</div>), 2000)); } function Page2() { // 模擬異步數(shù)據(jù)獲取失敗 return new Promise((_, reject) => setTimeout(() => reject(new Error('Error loading Page 2')), 2000)); }
六、startTransition:手動創(chuàng)建過渡
startTransition
是一個新的函數(shù),它允許你在狀態(tài)更新過程中創(chuàng)建一個過渡(transition)。你可以使用這個函數(shù)來延遲某些狀態(tài)更新,直到過渡完成。這對于實現(xiàn)更好的用戶體驗和性能優(yōu)化非常有用。
動畫與過渡的協(xié)同
在下面這個示例中,當用戶點擊按鈕時,handleClick
函數(shù)會使用 startTransition
創(chuàng)建一個過渡,并在過渡期間平滑地移動盒子。通過結(jié)合 CSS 動畫和 React 過渡,可以實現(xiàn)更自然、更流暢的交互體驗。
import { useState, startTransition } from 'react'; function AnimationTransitionExample() { const [position, setPosition] = useState(0); const handleClick = () => { // 使用 startTransition 創(chuàng)建過渡 startTransition(() => { setPosition(position + 100); }); }; return ( <div style={{ position: 'relative' }}> <div style={{ position: 'absolute', left: position, transition: 'left 0.5s ease-out', }} > Box </div> <button onClick={handleClick}>Move box</button> </div> ); }
七、useId 與 useSyncExternalStore:與外部數(shù)據(jù)源同步
這兩個新的 Hooks 提供了更好的支持,以便在 React 組件和外部數(shù)據(jù)源之間同步數(shù)據(jù)。useId
用于生成唯一的 ID,而 useSyncExternalStore
用于在組件和外部數(shù)據(jù)源之間同步數(shù)據(jù)。
實時聊天應用
在下面這個示例中,ChatRoom
組件使用 useSyncExternalStore
從外部數(shù)據(jù)源(chatStore
)獲取聊天消息列表。當外部數(shù)據(jù)源的數(shù)據(jù)發(fā)生變化時,組件會自動重新渲染。同時,每個 ChatMessage
組件都使用 useId
生成了一個唯一的 ID,以便在 DOM 中正確引用它們。
import { useId, useSyncExternalStore } from 'react'; function ChatMessage({ message }) { const id = useId(); return <div id={`message-${id}`}>{message}</div>; } function ChatRoom() { const messages = useSyncExternalStore( () => chatStore.subscribe, () => chatStore.getMessages() ); return ( <div> {messages.map((message) => ( <ChatMessage key={message.id} message={message.text} /> ))} </div> ); } const chatStore = { messages: [], subscribers: new Set(), subscribe(callback) { this.subscribers.add(callback); return () => { this.subscribers.delete(callback); }; }, getMessages() { return this.messages; }, addMessage(message) { this.messages.push(message); this.subscribers.forEach((callback) => callback()); }, };
總結(jié)以及預測
React新版本的并發(fā)機制提供了一系列新特性,包括自動批處理、異步渲染、新的 Hooks 和 Suspense 配置等。這些特性旨在幫助開發(fā)者更好地控制和優(yōu)化應用程序的性能和用戶體驗。通過這些新特性我看到了React在性能優(yōu)化和用戶體驗方面的巨大潛力。
下面是掌門人對于React并發(fā)機制的一些預測,若是大家與我想法不一致,還請嘴下留情。
- 更細粒度的并發(fā)控制:未來的React可能會提供更細粒度的并發(fā)控制,允許開發(fā)者根據(jù)具體場景定制渲染策略,以實現(xiàn)更高的性能和更低的開銷。
- 集成Web Workers:Web Workers為JavaScript提供了在單獨線程中運行代碼的能力,從而避免了主線程的阻塞。未來,React可能會更好地集成Web Workers,以實現(xiàn)更高效的并發(fā)處理。
- 更強大的Suspense功能:Suspense是React并發(fā)機制的核心組件之一,未來的版本可能會增強其功能,例如支持多個等待狀態(tài)、更細粒度的錯誤處理等。
- 優(yōu)化的數(shù)據(jù)流管理:React的上下文API和數(shù)據(jù)流管理一直是開發(fā)者關(guān)注的焦點。未來的React可能會進一步優(yōu)化這些方面,以提供更高效、更簡潔的數(shù)據(jù)流解決方案。
- 更好的服務器端渲染支持:隨著服務器端渲染(SSR)在現(xiàn)代Web應用中的重要性日益增加,React可能會提供更好的SSR支持,包括更快的首屏加載時間、更好的SEO優(yōu)化等。
從長遠來看,React的發(fā)展將更加注重性能、可維護性和開發(fā)者體驗,React目前的發(fā)展趨勢應該是將自身打造為一個全棧底層的基座,同時,隨著物聯(lián)網(wǎng)設備的普及,React也可能會拓展其在該領(lǐng)域的應用。
到此這篇關(guān)于一文帶你了解React中的并發(fā)機制的文章就介紹到這了,更多相關(guān)React并發(fā)機制內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
React特征學習Form數(shù)據(jù)管理示例詳解
這篇文章主要為大家介紹了React特征學習Form數(shù)據(jù)管理示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-09-09使用react-virtualized實現(xiàn)圖片動態(tài)高度長列表的問題
一般我們在寫react項目中,同時渲染很多dom節(jié)點,會造成頁面卡頓, 空白的情況。為了解決這個問題,今天小編給大家分享一篇教程關(guān)于react-virtualized實現(xiàn)圖片動態(tài)高度長列表的問題,感興趣的朋友跟隨小編一起看看吧2021-05-05React中使用react-json-view展示JSON數(shù)據(jù)的操作方法
react-json-view是一個用于顯示和編輯javascript數(shù)組和JSON對象的React組件,本文給大家分享React中使用react-json-view展示JSON數(shù)據(jù)的操作方法,感興趣的朋友一起看看吧2023-12-12