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

小推理:React18比老版React更優(yōu)秀的一個(gè)地方

開發(fā) 前端
React18已經(jīng)進(jìn)入RC(release candidate)階段,距離正式版只有一步之遙了。相比于老版「并發(fā)的React」,新版「并發(fā)的React」在render次數(shù)上會(huì)更有優(yōu)勢(shì)。

大家好,我卡頌。

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

v18新增了很多特性,今天,我們不聊新特性,而是來講講v18相比老版更優(yōu)秀的一個(gè)細(xì)節(jié):

  • v18中,組件render的次數(shù)可能更少。

狀態(tài)從何而來

在如下組件中:

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

App組件render后會(huì)執(zhí)行useState,返回num的最新值。

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

考慮如下觸發(fā)更新的代碼:

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

onClick執(zhí)行后觸發(fā)更新,更新導(dǎo)致App組件render,進(jìn)而useState執(zhí)行。

在useState內(nèi)部,會(huì)遵循如下流程計(jì)算num:

  1. update(100)將num變?yōu)?00。
  2. update(num + 1)將num變?yōu)?00 + 1 = 101。
  3. update(num => num * 3)將num變?yōu)?01 * 3 = 303。

即,App組件render時(shí),num為303。

所以,狀態(tài)的計(jì)算需要先收集觸發(fā)的更新,再在useState中統(tǒng)一計(jì)算。

對(duì)于上述例子,將更新分別命名為u0~u2,則狀態(tài)的計(jì)算公式為:

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

Concurrent帶來的變化

Concurrent(并發(fā))為React帶來了「優(yōu)先級(jí)」的概念,反映到「狀態(tài)計(jì)算」上,根據(jù)觸發(fā)更新的場(chǎng)景,更新?lián)碛胁煌瑑?yōu)先級(jí)(比如onClick回調(diào)中觸發(fā)的更新優(yōu)先級(jí)高于useEffect回調(diào)中觸發(fā)的更新)。

表現(xiàn)在計(jì)算狀態(tài)中的區(qū)別就是,如果某個(gè)更新優(yōu)先級(jí)低,則會(huì)被跳過。

假設(shè)上述例子中u1優(yōu)先級(jí)低,那么App組件render時(shí),計(jì)算num狀態(tài)的公式為:

// 其中u1因?yàn)閮?yōu)先級(jí)低,被跳過
baseState -> u0 -> u2 = newState

即:

  1. update(100)將num變?yōu)?00。
  2. update(num => num * 3)將num變?yōu)?00 * 3 = 300。

顯然這個(gè)結(jié)果是不對(duì)的。

所以,并發(fā)情況下React計(jì)算狀態(tài)的邏輯會(huì)更復(fù)雜。具體來講,可能包含多輪計(jì)算。

當(dāng)計(jì)算狀態(tài)時(shí),如果某次更新被跳過,則下次計(jì)算時(shí)會(huì)從被跳過的更新繼續(xù)往后計(jì)算。

比如上例中,u1被跳過。當(dāng)u1被跳過時(shí),num為100。此時(shí)的狀態(tài)100,以及u1和「他后面的所有更新」都會(huì)保存下來,參與下次計(jì)算。

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

下次更新的情況如下:

  1. 初始狀態(tài)為100,update(num + 1)將num變?yōu)?00 + 1 = 101。
  2. update(num => num * 3)將num變?yōu)?01 * 3 = 303。

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

「同步的React」 render一次,結(jié)果為303。

「并發(fā)的React」 render兩次,結(jié)果分別為300(中間狀態(tài)),303(最終狀態(tài))。

新舊Concurrent的區(qū)別

從上例我們發(fā)現(xiàn),組件render的次數(shù)受「有多少更新被跳過」影響,實(shí)際可能不止render兩次,而是多次。

在老版「并發(fā)的React」中,表示「優(yōu)先級(jí)」的是一個(gè)被稱為expirationTime的時(shí)間戳。比較「更新是否應(yīng)該被跳過」的算法如下:

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

在這種邏輯下,只要優(yōu)先級(jí)低,就會(huì)被跳過,就意味著多一次render。

在新版「并發(fā)的React」中,「優(yōu)先級(jí)」被保存在「31位的二進(jìn)制數(shù)」中。

舉個(gè)例子:

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

其中renderLanes是本次更新指定的「優(yōu)先級(jí)」。

比較「優(yōu)先級(jí)」的函數(shù)為:

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

其中:

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

u1.lane包含于renderLanes中,代表這個(gè)更新?lián)碛凶銐騼?yōu)先級(jí)。

u2.lane不包含于renderLanes中,代表這個(gè)更新沒有足夠優(yōu)先級(jí),被跳過。

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

u2.lane = 0b0000;

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

// true
isSubsetOfLanes(renderLanes, 0)

所以這個(gè)更新一定會(huì)在下次處理。換言之,在新版「并發(fā)的React」中,由于「優(yōu)先級(jí)原因被跳過」,導(dǎo)致的「重復(fù)render」,最多只會(huì)有2次。

總結(jié)

相比于老版「并發(fā)的React」,新版「并發(fā)的React」在render次數(shù)上會(huì)更有優(yōu)勢(shì)。

反映到用戶的感官上,用戶會(huì)更少看到「未計(jì)算完全的中間狀態(tài)」。

責(zé)任編輯:姜華 來源: 魔術(shù)師卡頌
相關(guān)推薦

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架構(gòu)

2021-06-22 07:30:07

React18Automatic b自動(dòng)批處理

2021-11-29 06:05:31

React組件前端

2022-03-30 14:22:55

ReactReact18并發(fā)特性

2024-04-15 12:54:00

ReactVue列表邏輯

2017-05-17 15:50:34

開發(fā)前端react

2021-11-30 05:45:48

React組件前端

2023-05-04 23:59:46

React開發(fā)工具

2023-12-21 10:26:30

??Prettier

2023-03-28 07:59:57

ReactReconciler

2022-07-06 15:07:47

React開發(fā)

2022-05-13 08:48:50

React組件TypeScrip

2022-03-25 08:31:09

ReactReact 18升級(jí)

2018-08-31 08:03:00

深度學(xué)習(xí)GBDT算法CatBoost

2021-07-02 05:31:53

ReactSolidJS前端

2022-04-18 08:57:32

React 18前端
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 精品国产一区二区 | 精品国产一区三区 | 天天干在线播放 | 久久精品小视频 | 日韩精品一区二区三区中文字幕 | 成人免费毛片片v | 精品国产乱码一区二区三区 | 97精品超碰一区二区三区 | 久久久久久久国产 | 一区二区三区四区国产 | 免费特级黄毛片 | 青青久草 | 欧美精品在线一区二区三区 | 亚洲日本视频 | 亚洲一区二区三区免费在线观看 | 欧美v在线观看 | 国产精品久久久久久久久久 | 日本不卡一区 | 欧美一级黑人aaaaaaa做受 | 91久久精品国产91久久 | 在线免费观看视频黄 | 天堂一区二区三区 | 中文字幕亚洲视频 | 欧美xxxⅹ性欧美大片 | 亚洲综合在线播放 | 黄色一级毛片 | 亚洲国产成人精品女人久久久 | 国产一区二区三区视频 | 日韩一区二区三区在线 | 久久国产精品-国产精品 | 国产在线精品一区二区 | 欧美日韩国产一区二区三区 | 亚洲欧洲中文日韩 | 国产成人av一区二区三区 | 日本中出视频 | 亚洲国产精品一区二区www | 欧美一级全黄 | 一区二区精品 | 99精品国产一区二区三区 | 欧美精品一二三 | 不卡一区二区三区四区 |