国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

悄悄告訴你:React18文檔里寫錯的地方

開發(fā) 前端
React作為一款維護了快10年的框架,在經(jīng)歷重大版本更新后要保持框架行為前后一致,實屬不易。

大家好,我卡頌

React18正式版已經(jīng)發(fā)布一段時間了,如果你升級到v18,且仍使用ReactDOM.render創(chuàng)建應(yīng)用,會收到如下報警:

大意是說:v18使用createRoot而不是render創(chuàng)建應(yīng)用,如果你仍使用render創(chuàng)建應(yīng)用,那么應(yīng)用的行為將同v17一樣。

React團隊之所以有底氣讓大家都升級到v18,使用createRoot,是因為他們作出了承諾:

大意是說:如果你升級到v18,只要不使用「并發(fā)特性」(比如useTransition),React會和之前版本表現(xiàn)一致(更新會同步、不可中斷)。

今天這篇文章想說的是:某些情況下,上述說法是錯誤的。

不說廢話,上示例示

例中有a、b兩個狀態(tài),首次渲染完2秒后會觸發(fā)a、b更新。

其中觸發(fā)b更新的方式比較特殊:模擬點擊,間接觸發(fā)b更新:

function App() {
const [a, setA] = useState(0);
const [b, setB] = useState(0);
const BtnRef = useRef<HTMLButtonElement>(null);
useEffect(() => {
setTimeout(() => {
setA(9000);
BtnRef.current?.click();
}, 2000);
}, []);
return (
<div>
<button
ref={BtnRef}
onClick={() => setB(1)}>
b: {b}
</button>
{Array(a).fill(0).map((_, i) => {
return <div key={i}>{a}</div>;
})}
</div>
);
}

完整示例地址[1]

現(xiàn)在我們有兩種掛載的方式。

v18之前的方式:

const rootElement = document.getElementById("root");
// v18之前創(chuàng)建應(yīng)用的方式
ReactDOM.render(<App/>, rootElement);

v18提供的方式:

const root = ReactDOM.createRoot(rootElement);
// v18創(chuàng)建應(yīng)用的方式
root.render(
<App />
);

為了看清這兩者的區(qū)別,有兩種方式:

調(diào)大setA(9000)中的值,使頁面渲染更多項。頁面渲染時卡頓越明顯,渲染順序的差異越明顯。

setTimeout(() => {
setA(9000);
BtnRef.current?.click();
}, 2000);

在react-dom.development.js的commitRootImpl方法中打斷點。

這個方法是React渲染時調(diào)用的方法,在這里打斷點可以看出頁面渲染的順序。

對于ReactDOM.render創(chuàng)建的應(yīng)用,觸發(fā)更新后渲染順序如下:

首先:

其次:

對于ReactDOM.createRoot創(chuàng)建的應(yīng)用,觸發(fā)更新后渲染順序如下:

首先:

其次:

渲染順序顯然是變了,這和React文檔里的說法是相悖的。

背后的原因是什么呢?

更新的優(yōu)先級,無處不在

先解釋下示例中的b為什么采用「觸發(fā)onClick事件」的方式間接觸發(fā)更新:

BtnRef.current?.click();

這是因為:不同方式觸發(fā)的更新有不同「優(yōu)先級」,onClick回調(diào)中觸發(fā)的更新是最高優(yōu)的,即「同步優(yōu)先級」。

那么問題來了,v18不使用并發(fā)特性,所有更新不都該是「同步、不可中斷」么?

這話是沒錯,更新本身是「同步、不可中斷」的。但是更新是需要調(diào)度的。

在示例中,如果采用ReactDOM.createRoot創(chuàng)建應(yīng)用,那么觸發(fā)更新時的優(yōu)先級如下:

setTimeout(() => {
// 觸發(fā)更新,優(yōu)先級為“默認優(yōu)先級”
setA(9000);
// 觸發(fā)更新,優(yōu)先級為“同步優(yōu)先級”
BtnRef.current?.click();
}, 2000);

接下來React的執(zhí)行流程如下:

  1. a觸發(fā)更新,優(yōu)先級為“默認優(yōu)先級”。
  2. 調(diào)度a的更新,優(yōu)先級為“默認優(yōu)先級”。
  3. b觸發(fā)更新,優(yōu)先級為“同步優(yōu)先級”。
  4. 調(diào)度b的更新,優(yōu)先級為“同步優(yōu)先級”。
  5. 此時發(fā)現(xiàn)已經(jīng)有個更新在調(diào)度(a的更新),且優(yōu)先級更低(默認優(yōu)先級 < 同步優(yōu)先級)。
  6. 取消a的更新的調(diào)度,轉(zhuǎn)而開始調(diào)度b的更新。
  7. 調(diào)度流程結(jié)束,開始同步、不可中斷的執(zhí)行b的更新。
  8. b對應(yīng)更新渲染到頁面中。
  9. 此時發(fā)現(xiàn)還有一個更新(a的更新),調(diào)度他。
  10. 調(diào)度流程結(jié)束,開始同步、不可中斷的執(zhí)行a的更新。
  11. a對應(yīng)更新渲染到頁面中。

可見,只要采用ReactDOM.createRoot創(chuàng)建應(yīng)用,那么「優(yōu)先級」的影響就會一直存在,與「使用了并發(fā)特性」的區(qū)別是:

  • 只有「默認優(yōu)先級」與「同步優(yōu)先級」。
  • 優(yōu)先級只會影響調(diào)度,不會中斷更新的執(zhí)行。

老版React的歷史包袱

那么采用ReactDOM.render創(chuàng)建的應(yīng)用執(zhí)行順序又是怎么一回事呢?

記不記得一道經(jīng)典(且毫無意義)的React面試題:React的更新是同步還是異步的?

下面兩種情況,a打印的結(jié)果是1么?

// 情況1
onClick() {
this.setState({a: 1});
console.log(a);
}
// 情況2
onClick() {
setTimeout(() => {
this.setState({a: 1});
console.log(a);
})
}

其中,情況2中a打印結(jié)果是1。

之所以會有這種情況,是React早期實現(xiàn)批處理時的瑕疵造成的,并不是什么有意為之的特性。

當React使用Fiber架構(gòu)重構(gòu)后,完全可以規(guī)避這個瑕疵。但為了與老版本行為保持一致,刻意實現(xiàn)成這樣。

所以,在我們的示例中,這兩個更新不會受到「優(yōu)先級」的影響,但會受到「為了兼容老版本」造成的影響:

setTimeout(() => {
setA(9000);
BtnRef.current?.click();
}, 2000);

React的執(zhí)行流程如下:

  1. a觸發(fā)更新,因為是在setTimeout中觸發(fā)的,所以會同步執(zhí)行后續(xù)更新流程。
  2. a對應(yīng)更新渲染到頁面中。
  3. b觸發(fā)更新,因為是在setTimeout中觸發(fā)的,所以會同步執(zhí)行后續(xù)更新流程。
  4. b對應(yīng)更新渲染到頁面中。

總結(jié)

React作為一款維護了快10年的框架,在經(jīng)歷重大版本更新后要保持框架行為前后一致,實屬不易。

更新順序的變化對一般應(yīng)用影響不大。

但是,如果你的應(yīng)用依賴更新后「頁面中當前的值」作出后續(xù)判斷,那么需要注意升級到v18后的這些細微變化。

參考資料

[1]完整示例地址:

https://codesandbox.io/s/strange-cartwright-iq1s2m?file=/src/index.tsx。

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

2022-03-16 17:01:35

React18并發(fā)的React組件render

2021-06-16 06:05:25

React18React

2021-11-01 19:49:55

React組件模式

2020-06-16 09:55:52

數(shù)據(jù)庫MySQL技術(shù)

2021-06-22 07:45:57

React18startTransiReact

2020-12-30 09:18:46

JVM內(nèi)部信息

2023-03-21 08:31:13

ReconcilerFiber架構(gòu)

2020-04-30 11:11:30

MySQLMGR數(shù)據(jù)庫

2015-02-11 09:37:14

2021-06-22 07:30:07

React18Automatic b自動批處理

2022-03-30 14:22:55

ReactReact18并發(fā)特性

2015-06-25 17:28:44

免費代理網(wǎng)絡(luò)安全

2016-06-27 16:29:04

戴爾閃存

2023-03-28 07:59:57

ReactReconciler

2021-11-29 06:05:31

React組件前端

2022-03-25 08:31:09

ReactReact 18升級

2022-04-26 06:43:12

文檔TCPLinux

2018-08-27 14:44:42

文檔云

2012-05-23 09:40:09

HTML5

2021-11-30 05:45:48

React組件前端
點贊
收藏

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

黄页网站一区| 亚洲精品欧美日韩专区| 国产精品二区三区| 中文不卡1区2区3区| 国产成人福利片| 上原亚衣av一区二区三区| 日韩精品免费一区| 精品欧美激情在线观看| 亚洲欧美日韩国产精品| 污网站免费看| 裸体一区二区| 成人性生交xxxxx网站| 国产一区二区| 亚洲综合视频网| 日韩一级性生活片| 午夜激情久久| 久久精品国产久精国产一老狼 | 女同互忝互慰dv毛片观看| 一本色道精品久久一区二区三区| 免费高清成人| 久99久在线| 亚洲专区视频| 中文字幕日韩av| 97香蕉超级碰碰久久免费软件| 经典三级在线| 亚洲午夜国产一区99re久久| 日本中文字幕亚洲| 99视频一区二区| 9191国产视频| 麻豆精品一二三| 日韩不卡av| 亚洲欧洲午夜| 欧美精品二区三区四区免费看视频| 9999国产精品| 国产精品亚洲综合天堂夜夜| 成人网18免费网站| 99r国产精品视频| 亚洲色图网站| 91精品久久久久久久久久| 欧美尿孔扩张虐视频| 亚洲综合色激情五月| 亚洲91视频| 99c视频在线| 久久国产精品亚洲77777| 亚洲国产激情一区二区三区| 久久午夜电影| 青青草综合视频| 亚洲精品国产第一综合99久久| 久久99久久| 日韩电影第一页| 国产成人一区二区三区影院| 在线观看国产一区| 一个色综合网站| 国产ktv在线视频| 国产成一区二区| 欧美韩国日本一区| av软件在线观看| 欧美一区二区成人6969| 黄色漫画在线免费看| 欧美一级高清免费播放| 精品一区二区三区的国产在线播放| 欧美xxxxx在线视频| 中文字幕日韩一区| 日本精品不卡| 99re6在线| 一区二区三区在线免费| 亚洲麻豆精品| xxxxx成人.com| 久久精品国产一区二区三区免费看 | 做爰高潮hd色即是空| 亚洲男人天堂一区| 久久xxx视频| 日本一区美女| 国产精品乱码久久久久久| 国产伦理精品| 中文字幕一区二区三区四区五区六区| 亚洲国产成人tv| 91蝌蚪精品视频| 日韩在线观看a| 亚洲精品在线网站| www国产亚洲精品久久麻豆| 国产白丝在线观看| 超碰10000| 欧美一区二区三区……| 亚洲黄色影片| 成人免费高清在线播放| 粗暴蹂躏中文一区二区三区| 免播放器亚洲| 91.xxx.高清在线| 欧美在线3区| 91精品国产全国免费观看| 久久精品123| 成人免费图片免费观看| 日本在线播放一区| 亚洲欧美日韩中文视频| 国产一区二区不卡老阿姨| 日本视频在线免费观看| 一区二区精品在线观看| 国产一区二区三区中文| 国产人妖乱国产精品人妖| 这里只有精品在线| 国产淫片在线观看| 美女av免费观看| 午夜精品一区二区三区在线 | 欧美综合久久| 欧美zozo| 国产不卡一区二区视频| 欧洲成人性视频| 欧美一级午夜免费电影| 亚洲日本一区二区| 国产福利不卡视频| 男人的天堂成人在线| yw.尤物在线精品视频| 欧洲日本在线| 在线国产视频| 男女免费网站| 亚洲高潮无码久久| 国产亚洲欧美日韩一区二区| 综合激情成人伊人| 美女mm1313爽爽久久久蜜臀| 成人高潮视频| 久久久久黄久久免费漫画| www.成人69.com| 激情图片qvod| 欧美一级日本a级v片| 热99精品只有里视频精品| 亚洲欧美日韩爽爽影院| 欧美性猛交xxxx富婆| 亚洲欧美另类久久久精品2019| 久久成人久久鬼色| 美女视频黄久久| 久久先锋资源| 久久三级福利| 激情成人综合| 欧美1区2区视频| 亚洲深深色噜噜狠狠爱网站| 精品久久国产| 99re6热只有精品免费观看| av男人一区| 福利在线午夜| 久久国产色av免费观看| 欧美激情视频免费观看| 国产精品12区| 精品理论电影| 91福利在线视频| 日韩欧美亚洲系列| 九七影院理伦片| 久久影院理伦片| 日韩欧美第一区| 色综合网站在线| 亚洲一区二区毛片| 久久精品凹凸全集| 天堂资源最新在线| 免费观看精品视频| 2019日本中文字幕| 欧美三级日韩三级国产三级| 人禽交欧美网站| 麻豆精品国产传媒mv男同| 九一成人免费视频| 看片一区二区| 91在线播放网站| 国产黄在线观看| 欧美一区二区影院| 日本中文字幕久久看| 久久精品人人爽| 亚洲黄色www网站| 色多多国产成人永久免费网站| 在线观看区一区二| 成人免费在线观看入口| 中文在线综合| 日韩精品视频在线看| 日韩免费影院| 色呦呦在线视频| 成人狠狠色综合| 男女污污的视频| 色总=综合色| 国产成人免费| 国产激情欧美| 久久资源中文字幕| 国产精品资源| 国产精品久久久久天堂| 亚洲综合在线第一页| 欧美日韩久久不卡| 日韩网站免费观看高清| 久久久久女教师免费一区| 欧美精品人人做人人爱视频| 久久精品国产精品国产精品污 | 116美女写真午夜一级久久| 欧美jizz18性欧美| 五月婷婷亚洲| 成人激情小说乱人伦| 在线视频欧美区| 欧美日韩高清影院| 亚洲天堂av综合网| 欧美精品免费在线观看| 国产麻豆日韩| 污黄色在线观看| 成人交换视频| 成人精品久久| 国产精品一级片|