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

小推理:React18比老版React更優秀的一個地方

開發 前端
React18已經進入RC(release candidate)階段,距離正式版只有一步之遙了。相比于老版「并發的React」,新版「并發的React」在render次數上會更有優勢。

大家好,我卡頌。

React18已經進入RC(release candidate)階段,距離正式版只有一步之遙了。

v18新增了很多特性,今天,我們不聊新特性,而是來講講v18相比老版更優秀的一個細節:

  • v18中,組件render的次數可能更少。

狀態從何而來

在如下組件中:

function App() {
const [num, update] = useState(0);
// ...省略

App組件render后會執行useState,返回num的最新值。

也就是說,組件必須render,才能知道最新的狀態。為什么會這樣呢?

考慮如下觸發更新的代碼:

const [num, update] = useState(0);
const onClick = () => {
update(100);
update(num + 1);
update(num => num * 3);
}

onClick執行后觸發更新,更新導致App組件render,進而useState執行。

在useState內部,會遵循如下流程計算num:

  1. update(100)將num變為100。
  2. update(num + 1)將num變為100 + 1 = 101。
  3. update(num => num * 3)將num變為101 * 3 = 303。

即,App組件render時,num為303。

所以,狀態的計算需要先收集觸發的更新,再在useState中統一計算。

對于上述例子,將更新分別命名為u0~u2,則狀態的計算公式為:

baseState -> u0 -> u1 -> u2 = newState

Concurrent帶來的變化

Concurrent(并發)為React帶來了「優先級」的概念,反映到「狀態計算」上,根據觸發更新的場景,更新擁有不同優先級(比如onClick回調中觸發的更新優先級高于useEffect回調中觸發的更新)。

表現在計算狀態中的區別就是,如果某個更新優先級低,則會被跳過。

假設上述例子中u1優先級低,那么App組件render時,計算num狀態的公式為:

// 其中u1因為優先級低,被跳過
baseState -> u0 -> u2 = newState

即:

  1. update(100)將num變為100。
  2. update(num => num * 3)將num變為100 * 3 = 300。

顯然這個結果是不對的。

所以,并發情況下React計算狀態的邏輯會更復雜。具體來講,可能包含多輪計算。

當計算狀態時,如果某次更新被跳過,則下次計算時會從被跳過的更新繼續往后計算。

比如上例中,u1被跳過。當u1被跳過時,num為100。此時的狀態100,以及u1和「他后面的所有更新」都會保存下來,參與下次計算。

在例子中即為u1、u2保存下來。

下次更新的情況如下:

  1. 初始狀態為100,update(num + 1)將num變為100 + 1 = 101。
  2. update(num => num * 3)將num變為101 * 3 = 303。

可見,最終的結果303與「同步的React」是一致的,只是需要render兩次。

「同步的React」 render一次,結果為303。

「并發的React」 render兩次,結果分別為300(中間狀態),303(最終狀態)。

新舊Concurrent的區別

從上例我們發現,組件render的次數受「有多少更新被跳過」影響,實際可能不止render兩次,而是多次。

在老版「并發的React」中,表示「優先級」的是一個被稱為expirationTime的時間戳。比較「更新是否應該被跳過」的算法如下:

// 更新優先級是否小于render的優先級
if (updateExpirationTime < renderExpirationTime) {
// ...被跳過
} else {
// ...不跳過
}

在這種邏輯下,只要優先級低,就會被跳過,就意味著多一次render。

在新版「并發的React」中,「優先級」被保存在「31位的二進制數」中。

舉個例子:

const renderLanes = 0b0101;
u1.lane = 0b0001;
u2.lane = 0b0010;

其中renderLanes是本次更新指定的「優先級」。

比較「優先級」的函數為:

function isSubsetOfLanes(set, subset) {
return (set & subset) === subset;
}

其中:

// true
isSubsetOfLanes(renderLanes, u1.lane)
// false
isSubsetOfLanes(renderLanes, u2.lane)

u1.lane包含于renderLanes中,代表這個更新擁有足夠優先級。

u2.lane不包含于renderLanes中,代表這個更新沒有足夠優先級,被跳過。

但是「被跳過的更新」(例子中的u2)的lane會被重置為0,即:

u2.lane = 0b0000;

顯然任何lanes都是包含0的:

// true
isSubsetOfLanes(renderLanes, 0)

所以這個更新一定會在下次處理。換言之,在新版「并發的React」中,由于「優先級原因被跳過」,導致的「重復render」,最多只會有2次。

總結

相比于老版「并發的React」,新版「并發的React」在render次數上會更有優勢。

反映到用戶的感官上,用戶會更少看到「未計算完全的中間狀態」。

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

2022-04-27 07:37:42

ReactReact18

2021-06-16 06:05:25

React18React

2021-11-01 19:49:55

React組件模式

2021-06-22 07:45:57

React18startTransiReact

2023-03-21 08:31:13

ReconcilerFiber架構

2021-06-22 07:30:07

React18Automatic b自動批處理

2024-04-15 12:54:00

ReactVue列表邏輯

2021-11-29 06:05:31

React組件前端

2022-03-30 14:22:55

ReactReact18并發特性

2017-05-17 15:50:34

開發前端react

2021-11-30 05:45:48

React組件前端

2023-05-04 23:59:46

React開發工具

2023-12-21 10:26:30

??Prettier

2022-03-25 08:31:09

ReactReact 18升級

2022-07-06 15:07:47

React開發

2022-05-13 08:48:50

React組件TypeScrip

2018-08-31 08:03:00

深度學習GBDT算法CatBoost

2023-03-28 07:59:57

ReactReconciler

2022-04-18 08:57:32

React 18前端

2021-07-02 05:31:53

ReactSolidJS前端
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲欧美日韩久久久 | 一级特黄网站 | 精品二区视频 | 亚洲欧美视频一区二区 | h片在线看 | 色综合av| 久久久久亚洲精品 | 久久91精品久久久久久9鸭 | 久久青青 | 日本精品视频 | 日韩一级 | 久久精品电影 | 69堂永久69tangcom| 久久国产高清 | 国产精品久久久久久久久久久久午夜片 | 精品一区二区久久久久久久网站 | 91精品国产综合久久久动漫日韩 | 日韩有码在线播放 | 秋霞电影一区二区 | 国产综合视频 | 黄色成人av | 日本大香伊一区二区三区 | 精品区 | 夜夜操天天艹 | 波多野吉衣久久 | 欧美日韩国产在线观看 | 久久一| 中文字幕电影在线观看 | 国产91精品网站 | 超碰日韩 | 91久久| 奇米久久久 | 在线免费观看黄色 | 日韩精品一区二区三区第95 | 精品成人 | 精品一区二区三区免费视频 | 欧美精品久久久 | 午夜成人在线视频 | 国产精品精品3d动漫 | 日韩精品一区二区三区中文字幕 | 久久天堂网 |