成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

React如何原生實現防抖?

開發 前端
ouseTransition是一個新增的原生Hook,用于「以較低優先級執行一些更新」。在我們的Demo中有ctn與num兩個狀態,其中ctn與輸入框的內容受控。

大家好,我卡頌。

作為前端,想必你對防抖(debounce)、節流(throttle)這兩個概念不陌生。

在React18中,基于新的并發特性,React原生實現了防抖的功能。

今天我們來聊聊這是如何實現的。

useTransition Dem

ouseTransition是一個新增的原生Hook,用于「以較低優先級執行一些更新」。

在我們的Demo中有ctn與num兩個狀態,其中ctn與輸入框的內容受控。

當觸發輸入框onChange事件時,會同時觸發ctn與num狀態變化。其中「觸發num狀態變化的方法」(即updateNum)被包裹在startTransition中:

function App() {
const [ctn, updateCtn] = useState('');
const [num, updateNum] = useState(0);
const [isPending, startTransition] = useTransition();
return (
<div >
<input value={ctn} onChange={({target: {value}}) => {
updateCtn(value);
startTransition(() => updateNum(num + 1))
}}/>
<BusyChild num={num}/>
</div>
);
}

num會作為props傳遞給BusyChild組件。在BusyChild中通過while循環人為增加組件render所消耗的時間:

const BusyChild = React.memo(({num}: {num: number}) => {
const cur = performance.now();
// 增加render的耗時
while (performance.now() - cur < 300) {}
return <div>{num}</div>;
})

所以,在輸入框輸入內容時能明顯感到卡頓。

在線示例地址[1]。

按理說,onChange中會同時觸發ctn與num的狀態變化,他們在視圖中的顯示應該是同步的。

然而實際上,輸入框連續輸入一段文字(即ctn的狀態變化連續展示在視圖中)后,num才會變化一次。

如下圖,初始時輸入框沒有內容,num為0:

輸入框輸入很長一段文字后,num才變為1:

這種效果就像:被startTransition包裹的更新都有「防抖」的效果一樣。

這是如何實現的呢?

什么是lane

在React18中有一套「更新優先級機制」,不同地方觸發的更新擁有不同優先級。優先級的定義依據是符合用戶感知的,比如:

  • 用戶不希望輸入框輸入文字會有卡頓,所以onChange事件中觸發的更新是同步優先級(最高優)。
  • 用戶可以接受請求發出到返回之間有等待時間,所以useEffect中觸發的更新是默認優先級。

那么優先級怎么表示呢?用一個31位的二進制,被稱為lane。

比如「同步優先級」和「默認優先級」定義如下:

const SyncLane =    0b0000000000000000000000000000001;
const DefaultLane = 0b0000000000000000000000000010000;

數值越小優先級越大,即SyncLane < DefaultLane。

那么React每次更新是不是選擇一個優先級,然后執行所有組件中「這個優先級對應的更新」呢?

不是。如果每次更新只能選擇一個優先級,那靈活性就太差了。

所以實際情況是:每次更新,React會選擇一到多個lane組成一個批次,然后執行所有組件中「包含在這個批次中的lane對應的更新」

這種組成批次的lane被稱為lanes。

比如,如下代碼將SyncLane與DefaultLane合成lanes:

// 用“按位或”操作合并lane
const lanes = SyncLane | DefaultLane;

entangle機制

可以看到,lane機制本質上就是各種位運算,可以設計的很靈活。

在此基礎上,有一套被稱為entangle(糾纏)的機制。

entangle指一種lane之間的關系,如果laneA與laneB糾纏,那么某次更新React選擇了laneA,則必須帶上laneB。

也就是說laneA與laneB糾纏在一塊,同生共死了。

除此之外,如果laneA與laneC糾纏,此時laneC與laneB糾纏,那么laneA也會與laneB糾纏。

那么entangle機制與useTransition有什么關系呢?

被startTransition包裹的回調中觸發的更新,優先級為TransitionLanes中的一個。

TransitionLanes中包括16個lane,分別是TransitionLane1到TransitionLane16:

而transition相關lane會發生糾纏。

在我們的Demo中,每次onChange執行,都會創建兩個更新:

onChange={({target: {value}}) => {
updateCtn(value);
startTransition(() => updateNum(num + 1))
}

其中:

  • updateCtn(value)由于在onChange中觸發,優先級為SyncLane。
  • updateNum(num + 1)由于在startTransition中觸發,優先級為TransitionLanes中的某一個。

當在輸入框中反復輸入文字時,以上過程會反復執行,區別是:

  • SyncLane由于是最高優先級,會被執行,所以我們會看到輸入框中內容變化。
  • TransitionLanes相關lane優先級比SyncLane低,暫時不會執行,同時他們會產生糾纏。

為了防止某次更新由于優先級過低,一直無法執行,React有個「過期機制」:每個更新都有個過期時間,如果在過期時間內都沒有執行,那么他就會過期。

過期后的更新會同步執行(也就是說他的優先級變得和SyncLane一樣)。

在我們的例子中,startTransition(() => updateNum(num + 1))會產生很多糾纏在一塊的TransitionLanes相關lane。

過了一段時間,其中某個lane過期了,于是他優先級提高到和SyncLane一樣,立刻執行。

又由于這個lane與其他TransitionLanes相關lane糾纏在一起,所以他們會被一起執行。

這就表現為:在輸入框一直輸入內容,但是num在視圖中顯示的數字過了會兒才變化。

總結

今天我們聊了useTransition內部的一些實現,涉及到:

  • lane模型。
  • entangle機制。
  • 更新過期機制。

最有意思的是,由于不同電腦性能不同,瀏覽器幀率會變動,所以在不同電腦中React會動態調節防抖的效果。

這就相當于不需要你手動設置debounce的時間參數,React會根據電腦性能動態調整。

參考資料

[1]在線示例地址:

??https://codesandbox.io/s/immutable-glade-u0m6vv?file=/src/App.js。??

責任編輯:姜華 來源: 魔術師卡頌
相關推薦

2024-05-28 09:26:46

2023-12-18 07:37:17

JavaScript防抖節流

2024-03-08 08:26:20

防抖節流delay?

2024-06-14 09:30:58

2021-08-03 06:57:36

Js事件節流

2022-04-14 08:00:00

Cypress測試開發

2024-08-29 15:26:21

2023-12-21 08:51:37

防抖節流Vue.js

2025-07-02 08:00:00

防抖SpringBoot開發

2024-09-13 10:21:50

2010-09-27 13:16:42

2021-12-09 10:57:19

防抖函數 Debounce

2023-08-29 08:28:43

React并發更新

2024-10-12 09:33:24

消息隊列多線程并行編程

2022-02-22 08:29:59

Vue前端防抖

2022-08-21 09:41:42

ReactVue3前端

2020-10-21 08:38:47

React源碼

2021-09-28 05:51:25

PostTaskReact瀏覽器

2016-11-23 16:48:20

react-nativandroidjavascript

2011-03-07 10:26:04

FileZilla
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 91精品在线观看入口 | 一区二区三区四区五区在线视频 | 国产视频一区二区三区四区五区 | 波多野结衣一区二区 | 色婷婷综合久久久中字幕精品久久 | 性欧美精品一区二区三区在线播放 | 日韩一级免费电影 | 中文在线www | 久久综合av| 欧美日韩在线一区 | 亚洲视频在线观看 | 97精品久久 | 乱一性一乱一交一视频a∨ 色爱av | 久久91 | 日本一道本视频 | 亚洲欧洲一区二区 | 日本三级网站在线 | 中文字幕在线看第二 | 亚洲一区二区久久 | 日本一卡精品视频免费 | 欧美日韩国产一区二区三区不卡 | 国产精品毛片久久久久久 | 黄免费观看视频 | 日韩精品一区二区三区中文在线 | 亚洲欧美在线免费观看 | 91av在线电影 | 成人亚洲综合 | 天天天天天操 | 亚洲欧美日韩国产综合 | 四虎影院新网址 | 人人爽人人爽 | 国产精品高潮呻吟 | 伊人av在线播放 | 久久久久久国产精品久久 | 国产乱码精品一区二区三区忘忧草 | 激情五月婷婷在线 | 精品粉嫩aⅴ一区二区三区四区 | 在线成人| 古装人性做爰av网站 | 黄色网址大全在线观看 | 久久一热 |