精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

看完 React Conext 源碼,就知道怎么繞過 Provider 修改它了

開發(fā) 前端
本文就從源碼層面來講下 cotnext 的原理,而且我們能從中發(fā)現(xiàn)一些 hack 的小技巧。

context 是 React 提供的特性,可以實(shí)現(xiàn)任意層級(jí)組件之間的數(shù)據(jù)傳遞。

可能大家用過 context,但是不知道它是怎么實(shí)現(xiàn)的。

本文就從源碼層面來講下 cotnext 的原理,而且我們能從中發(fā)現(xiàn)一些 hack 的小技巧。

首先,我們先過一下 context 的使用方式:

context 的使用

有這樣的 3個(gè)組件,One、Two、Three:

我們想不通過 props 從 One 傳遞數(shù)據(jù)到 Three,這時(shí)候就可以用 context 了:

調(diào)用 createContext 來創(chuàng)建 context 對(duì)象,初始化數(shù)據(jù)是 'dong'。

Three 組件里就可以通過 useContext 把 context 數(shù)據(jù)取出來了:

除了初始化的時(shí)候可以傳入,后面也可以通過 Provider 來修改 context 數(shù)據(jù):

我們通過 Provider 傳入了新的 value,覆蓋了初始值,這樣 useContext 拿到的值就變了:

函數(shù)組件是用 useContext 的 hook 來取,class 組件則是用 Consumer 來取:

我們依然是通過 createContext 創(chuàng)建 context 對(duì)象,通過 Provider 修改了 value。

現(xiàn)在 Three 變成了 class 組件,所以使用 context 的方式要通過 Consumer,它的 children 部分傳入 render 函數(shù),參數(shù)里就能拿到 context 數(shù)據(jù):

這分別是 class 組件和 function 組件使用 context 的方式,我們小結(jié)一下:

context 使用 React.createContext 創(chuàng)建,可以傳入初始值,后面也可以通過 Provider 來修改其中的值,使用 context 值的時(shí)候,如果是 function 組件,可以通過 useContext 的 hook 來取,而 class 組件是用 Consumer 傳入一個(gè) render 函數(shù)的方式來取。

學(xué)會(huì)了 context 怎么用,我們?cè)賮砜聪滤膶?shí)現(xiàn)原理:

context 的實(shí)現(xiàn)

首先我們看下 createContext 的源碼:

它創(chuàng)建了一個(gè) context 對(duì)象,有 _currentValue 屬性,一看就是保存值的,還有 Consumer 和 Provider 兩個(gè)屬性。

Consumer 和 Provider 都是通過 _context 保存了 context 對(duì)象的引用。

并且它們都有 $$typeof 來標(biāo)識(shí)類型。

這就是 context 對(duì)象的結(jié)構(gòu):

那這個(gè) context 對(duì)象是怎么結(jié)合到 React 渲染流程里的呢?

就是通過 jsx 結(jié)合的呀:

jsx 編譯以后會(huì)產(chǎn)生 render function。

比如上面那段 jsx 編譯后是這樣的:

新版 React 不調(diào)用 React.createElement 了,而是 jsx 函數(shù),也就是上面的 jsxDev。

看這第一個(gè)參數(shù)是啥,有 $$typeof 和 _context 屬性,不就是我們傳入的 context.Provider 么:

value 是在 props 參數(shù)里傳入的:

jsx 執(zhí)行會(huì)產(chǎn)生一個(gè)個(gè) vdom:

這樣 context 就保存到了 vdom 節(jié)點(diǎn)上。

那遞歸渲染的時(shí)候不就能從 vdom 拿到 context 了么?

別著急,React 現(xiàn)在不是 vdom 直接渲染了,而是會(huì)先把 vdom 轉(zhuǎn)成 fiber,這個(gè)過程叫做 reconcile:

fiber 的結(jié)構(gòu)中保存了兄弟節(jié)點(diǎn)和父節(jié)點(diǎn)的引用,這是 vdom 所沒有的,vdom 只有子節(jié)點(diǎn)的引用,所以 vdom 變成 fiber 以后就變成了可打斷的,因?yàn)榫退銛嗔艘材苷业叫值芄?jié)點(diǎn)和父節(jié)點(diǎn)繼續(xù)處理。

那保存在 vdom 中的 context 不就自然的轉(zhuǎn)移到了 fiber 節(jié)點(diǎn)上了么?

創(chuàng)建 fiber 的代碼是這樣的:

調(diào)用 createFiber 最終會(huì) new FiberNode

然后也是創(chuàng)建一個(gè)對(duì)象:

這個(gè)和 vdom 差別不大,只不過屬性不一樣了。

你看這里的 fiber.type,不就是保存在 vdom 上的 context.Provider 對(duì)象么?

那之后這個(gè) fiber 節(jié)點(diǎn)是怎么處理的呢?

你會(huì)發(fā)現(xiàn)在處理 fiber 節(jié)點(diǎn)的時(shí)候,會(huì)判斷 fiber.tag,不同的類型做不同的處理:

FunctionComponent 和 ClassComponent 的 fiber 節(jié)點(diǎn)的處理就不同。

下面可以找到 ContextProvider 的:

它的實(shí)現(xiàn)就是修改了 context 中的值:

pushProvider 就是最終修改 context 值的地方:

通過 _context 拿到了 Provider 所引用的 context 對(duì)象,然后修改它的 _currentValue 屬性,也就是 context 中的值。

對(duì)照著這個(gè) context 對(duì)象的結(jié)構(gòu)一看就明白了:

同理,后面處理到 Consumer 的時(shí)候也是這樣拿到 context 的:

ContextConsumer 的 fiber 節(jié)點(diǎn)也會(huì)做專門的處理:

workInProgress 就是當(dāng)前 fiber 節(jié)點(diǎn),它的 type 保存了 context.Consumer 對(duì)象。

我們通過 readContext 拿到其中的值,也就是取 _currentValue 屬性。

拿到最新的 context 中的值后就觸發(fā)子組件的渲染:

所以說為什么 Consumer 必須要傳入一個(gè) render 函數(shù)作為子節(jié)點(diǎn)不就清楚了么:

這樣我們就取到了 context 中的值,并觸發(fā)了子組件的渲染。

使用 context 的方式還有 useContext 的 hook,其實(shí)那個(gè)也是一樣的:

useContext 也是調(diào)用了 readContext 來讀取了 context 的 _currentValue 屬性:

當(dāng)然,useContext 的 context 不是從 fiber.type 來取的,而是用的傳入的 context:

但是都是引用的同一個(gè)對(duì)象,在 Provider 里修改了 context 的 value,這里取到的 context 同樣也是新的。

我們小結(jié)下 context 的實(shí)現(xiàn)原理:

createContext 會(huì)創(chuàng)建 context 對(duì)象,它有 _currentValue 保存值,還引用了 Provider 和 Consumer 兩個(gè)對(duì)象,Provider 和 Consumer 里有 _context 屬性引用了 context。

在 jsx 渲染的時(shí)候會(huì)把 Provider 和 Consumer 對(duì)象保存到 vdom 上,后面 reconcile 的時(shí)候會(huì)轉(zhuǎn)移到 fiber 的 type 屬性上,處理 fiber 節(jié)點(diǎn)的時(shí)候會(huì)根據(jù)類型做不同的處理:

如果是 Provider,就會(huì)根據(jù)傳入的 value 修改 context 的值,也就是 _currentValue 屬性

如果是 Consumer,則會(huì)讀取 context 的值然后觸發(fā)子組件的渲染。

函數(shù)組件會(huì)使用 useContext 的 hook,最終也是讀取了同一個(gè) context 的 _currentValue 的 值

理清了 context 的實(shí)現(xiàn)原理,我們是不是能發(fā)現(xiàn)一些 hack 的技巧呢?

比如 Provider 其實(shí)就是修改 _currentValue 的,那我們自己修改 context._currentValue 不就不用 Provider 了?

試一下:

用 Provider 是這樣的:

其實(shí)直接修改 _currentValue 也可以:

但是不推薦這樣寫,因?yàn)檫@是個(gè)私有屬性,萬一哪一天變了呢?

總結(jié)

context 是 React 提供的任意層級(jí)組件之間通信的機(jī)制,我們先過了一遍它的使用方式:

通過 createContext 來創(chuàng)建 context 對(duì)象,可以傳入初始值,可以通過 jsx 里的 context.Provider 來修改 context 值,通過 context.Consumer 來拿到 context 的值,如果是函數(shù)組件,是通過 useContext 的 hook 來取。

然后通過源碼理清了 context 的實(shí)現(xiàn)原理:

jsx 里的 Provider 和 Consumer 對(duì)象會(huì)被保存到 vdom 中,最后會(huì)轉(zhuǎn)移到 fiber 節(jié)點(diǎn)的 type 屬性上,fiber 處理的時(shí)候,對(duì) Provider 會(huì)修改 context 的 value,而 Consumer 則會(huì)取出 context 的值然后觸發(fā)子組件渲染。函數(shù)組件的 useContext 的 hook 也是從同一個(gè) context 對(duì)象讀取的數(shù)據(jù)。

然后我們發(fā)現(xiàn)了繞過 Provider 修改 context 的方式,就是直接修改 _currentValue,但是不推薦這樣做,因?yàn)樗接袑傩圆灰欢ㄉ稌r(shí)候就變了。

context 是這樣實(shí)現(xiàn)的,其他特性的實(shí)現(xiàn)原理也大同小異,只不過是掛到了不同的屬性上,處理 fiber 的時(shí)候做了分成了不同的類型來處理。

理清 context 的原理之后,你是否對(duì) vdom、fiber,還有 reconcile 的過程都有更深的理解了呢?

責(zé)任編輯:姜華 來源: 神光的編程秘籍
相關(guān)推薦

2019-06-05 15:20:00

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

2020-07-20 10:20:30

this前端代碼

2022-07-01 13:38:48

霧計(jì)算邊緣計(jì)算

2022-08-25 09:08:40

微服務(wù)架構(gòu)

2016-03-09 19:52:02

無線應(yīng)用Wi-Fi定位

2021-03-14 15:58:26

手機(jī)定位系統(tǒng)

2019-05-16 08:51:22

物聯(lián)網(wǎng)獲利IOT

2023-10-08 08:41:04

JavaPython編程語言

2022-09-02 19:10:46

高并發(fā)架構(gòu)系統(tǒng)

2021-05-07 06:15:32

編程開發(fā)端口掃描

2018-10-31 11:41:49

Python代碼語言

2020-02-18 16:53:48

機(jī)械硬盤SMRPMR

2019-12-12 10:02:29

滴滴數(shù)據(jù)中臺(tái)

2022-01-17 21:13:32

Windows 10Windows微軟

2023-05-09 13:55:08

GPT-4AI

2019-08-02 15:35:02

工具代碼開發(fā)

2020-05-22 13:00:45

蘋果安卓手機(jī)

2015-08-14 10:07:06

2018-07-24 11:21:25

程序員加班月薪

2020-06-28 07:49:06

WiFi 6WiFi 5網(wǎng)絡(luò)技術(shù)
點(diǎn)贊
收藏

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

激情五月深爱五月| 欧美爱爱视频免费看| 国产精品无码天天爽视频| 在线看片不卡| 亚洲国产欧美一区二区丝袜黑人| 亚洲精品无码久久久久久| www.在线视频.com| 国产精品综合一区二区| 欧美在线一区二区三区四| 日本不卡一区视频| 国产伦精品一区二区三区免费优势| 欧美性videos高清精品| 日本黄色播放器| 亚洲 欧美 激情 另类| 蜜桃视频一区二区| 国内精品小视频在线观看| 成人无码av片在线观看| 91蜜桃臀久久一区二区| 欧美日韩中字一区| 国产免费观看高清视频| 久久久久久久久免费视频| 91毛片在线观看| 亚洲最大福利视频| 日韩不卡高清视频| 亚洲精品日本| 欧美日韩国产第一页| 亚洲AV无码成人精品区明星换面 | 日韩精品一区二区久久| 亚洲第一视频网站| 1314成人网| 国产精品蜜月aⅴ在线| 欧美日韩一区二区在线| 国产精品videossex国产高清| 91激情在线| 久久这里只有精品首页| 国产麻豆乱码精品一区二区三区| 一级黄色片在线播放| 天堂av在线一区| 97香蕉久久超级碰碰高清版| 免费在线一级片| 影视一区二区| 欧美成aaa人片在线观看蜜臀| 特级西西人体高清大胆| 国语产色综合| 亚洲天堂第一页| 性欧美13一14内谢| 日韩精品福利一区二区三区| 亚洲第一黄色网| 男女性杂交内射妇女bbwxz| 精品一区91| 欧美一区二区视频在线观看| 免费网站在线观看黄| 黄色精品视频网站| 欧美三级乱人伦电影| wwwwxxxx日韩| 成人1区2区| 欧美日韩三级一区| gai在线观看免费高清| 国产精品伊人| 欧美精品亚洲二区| 亚洲热在线视频| 精品一区二区三区中文字幕视频 | 秘密基地免费观看完整版中文| 国产高清亚洲| 日韩一二三区视频| 亚洲av无码一区东京热久久| 国产毛片久久久| 亚洲美女精品久久| av永久免费观看| 国产韩日影视精品| 色综合色综合久久综合频道88| 欧美人禽zoz0强交| 在线不卡欧美| 日本久久久a级免费| 日批视频免费观看| 国产精品一区二区久久不卡| 国产精品亚洲一区| 国产黄在线看| 中文字幕一区二区在线观看| 最新av在线免费观看| wwww在线观看免费视频| 欧美日韩在线影院| 亚洲久久中文字幕| 亚洲精品国产九九九| 日韩黄色av网站| 神马久久久久久久久久久| 亚欧美无遮挡hd高清在线视频 | 欧美人妻一区二区| 亚洲一区二区伦理| 国产精品嫩草影院一区二区| 国产草草影院ccyycom| 2欧美一区二区三区在线观看视频 337p粉嫩大胆噜噜噜噜噜91av | 国产福利资源一区| 亚洲视频在线观看| 久操免费在线视频| 青娱乐精品视频| 国产另类第一区| 777电影在线观看| 亚洲综合久久久久| 蜜臀视频一区二区三区| 日韩一区二区三区精品| 亚洲日本成人女熟在线观看| 一区二区三区四区五区| 99在线|亚洲一区二区| 国产日韩在线精品av| 人人妻人人澡人人爽久久av | 亚洲精品中文综合第一页| 91国内在线| 色婷婷久久久久swag精品| 国产999免费视频| 国产成人三级| 国模精品视频一区二区| 一级黄色片在线播放| 久久香蕉国产线看观看99| 欧美大片免费播放| 色猫猫成人app| 亚洲精品ady| 欧美黑人性猛交xxx| 蜜臀久久久99精品久久久久久| 精品久久sese| 污网站在线免费看| 欧美日韩电影在线播放| 久久午夜夜伦鲁鲁片| 你懂的一区二区| 国产精品青青在线观看爽香蕉 | 亚洲人成在线观看网站高清| 久久久久免费看| 狠狠色狠狠色综合系列| 香蕉久久免费影视| 国产日韩电影| 日韩电影中文字幕av| 久久久美女视频| 国产精品综合二区| 六月婷婷激情网| 亚洲资源在线| 久久久精品国产一区二区| 成人一级免费视频| 久久综合狠狠综合久久综合88| 欧美日韩精品在线一区二区| av自拍一区| 久久久久在线观看| 亚洲精品视频网| 洋洋av久久久久久久一区| 日本黄色一级网站| 911精品美国片911久久久| 国产精品视频精品| 成人18在线| 欧美日韩激情在线| 特黄一区二区三区| 久久99久久99| 国产日产欧美一区二区| 日韩成人在线看| 欧美日韩国产成人在线| 亚洲精品国产精品国| 亚洲永久免费视频| 影音先锋黄色资源| 夜夜爽av福利精品导航| 欧美1o一11sex性hdhd| 成人影院网站| 中文精品99久久国产香蕉| 在线观看毛片网站| 亚洲色图在线播放| 69亚洲乱人伦| 噜噜噜躁狠狠躁狠狠精品视频| 日本福利一区二区三区| jizz亚洲女人高潮大叫| 久久精品亚洲一区| 亚洲精品一级片| 欧美性生交xxxxx久久久| 欧美日韩高清丝袜| 久久99久久99| 欧美激情视频免费看| 青青草这里只有精品| 国产精品激情av电影在线观看 | 高h放荡受浪受bl| 欧美性极品xxxx娇小| 日本女人性生活视频| 国产精选一区二区三区| 97超碰青青草| 欧美韩日一区| 国产精品视频入口| 日韩和的一区二在线| 久久影视电视剧免费网站清宫辞电视| 国内精品久久久久久久久久久| 偷拍日韩校园综合在线| 女人十八毛片嫩草av| 国产精品一区二区三区四区| 欧美成人免费高清视频| 91精品亚洲| 欧美二区三区在线| 国产精品一区二区精品视频观看| 久久久久久久影院| 国产女人在线视频| 欧美成人艳星乳罩| 国产偷人爽久久久久久老妇app| 亚洲日本在线a| 日本黄色特级片| 国产精品白丝jk黑袜喷水| 男人日女人视频网站| 欧美成人直播| 免费观看成人在线| 日本亚洲视频| 国产精品无av码在线观看| bl在线肉h视频大尺度| 色偷偷综合社区| 午夜视频在线播放| 91精品国产综合久久精品麻豆 | 欧美丰满少妇xxxxx高潮对白| 国产精品成人aaaa在线| 成人欧美一区二区三区黑人麻豆 | 国产精品久久久久久久app| 污片在线免费观看| www.欧美精品| 精品视频二区| 亚洲激情 国产| 精品国产亚洲AV| 欧美日韩国产综合久久| 色av性av丰满av| 亚洲成人免费在线观看| 日韩一区二区三区四区在线| 中文成人av在线| 三上悠亚影音先锋| 91在线观看下载| 在线中文字日产幕| 国产麻豆精品久久一二三| 国产视频1区2区3区| 久久字幕精品一区| 无码人妻丰满熟妇区96| 亚洲理论在线| 男女日批视频在线观看| 欧美日韩一视频区二区| 懂色av一区二区三区四区五区| 欧美手机视频| 四虎永久在线精品免费一区二区| 亚洲v天堂v手机在线| 精品不卡一区二区三区| 国产精品调教视频| 国产精品久久国产三级国电话系列| 国产精品一区三区在线观看| 成人h视频在线观看播放| 成人在线视频免费看| 国产精品日韩在线一区| 中文字幕日本一区二区| 国产精品久久久久久久久久小说| 欧洲一级精品| 国产精品中文字幕久久久| 国产成人福利夜色影视| 91精品久久久久久久久久久久久| 四虎在线精品| 亚洲a∨日韩av高清在线观看| 4438五月综合| 亚洲一区二区三区四区在线播放 | 亚洲精品理论电影| 少妇激情av一区二区| 亚洲女在线观看| yw193.com尤物在线| 综合国产在线观看| 黄色av电影在线观看| 九九热精品在线| 91色在线看| 清纯唯美日韩制服另类| 台湾成人免费视频| 国产一区欧美二区三区| 成人污污视频| 国产日韩一区欧美| 外国成人在线视频| 亚洲欧美国产精品桃花| 羞羞答答成人影院www| 男人添女人荫蒂免费视频| 国产精品视区| 久久婷五月综合| 国产成人在线视频播放| 国产又黄又粗又猛又爽的视频 | 欧美卡一卡二卡三| 精品国产精品三级精品av网址| 狠狠狠狠狠狠狠| 91麻豆精品国产91久久久资源速度| 性生活视频软件| 日韩精品久久久久久福利| av福利精品| 欧美高清一级大片| 欧美成人ⅴideosxxxxx| 成人午夜在线观看| 精品久久ai| 在线观看成人av| 国产日韩欧美一区在线| 国产视频1区2区3区| 成人国产精品免费观看视频| 小早川怜子久久精品中文字幕| 亚洲精品乱码久久久久久久久| 黄网在线观看视频| 91麻豆精品国产自产在线| 天堂中文资源在线| 久久精品91久久香蕉加勒比| f2c人成在线观看免费视频| 国产精品亚洲网站| 加勒比久久高清| 一区二区免费在线观看| 一本久道久久久| 交换做爰国语对白| 久久久国产精品午夜一区ai换脸| 少妇aaaaa| 欧美中文字幕一区| 日本黄色不卡视频| 欧美大尺度激情区在线播放| 亚洲黄色网址| 超碰97国产在线| 国产韩日影视精品| 91n.com在线观看| 暴力调教一区二区三区| 91高清免费看| 欧美色区777第一页| 头脑特工队2免费完整版在线观看| 欧美成人高清视频| 成人精品国产| 欧美日韩一区综合| 亚洲精品资源| 伦理片一区二区| 亚洲精品伦理在线| 一区二区 亚洲| 一区二区三区国产视频| 在线观看爽视频| 国产在线精品日韩| 国产精品大片| 潘金莲一级淫片aaaaa| 国产精品理论在线观看| 中文字幕一区二区三区四区欧美| 亚洲成人激情在线观看| 97超碰资源站在线观看| 国产在线观看精品| 手机在线电影一区| 午夜免费一区二区| 久久精品无码一区二区三区 | 欧美人与禽zozo性伦| 粉嫩av一区| 国产精品久久久91| 精品72久久久久中文字幕| 97超碰青青草| www久久久久| 免费无码国产精品| 国产亚洲综合久久| 日韩高清成人| 色综合电影网| 久久国内精品自在自线400部| 日本污视频网站| 欧美色网一区二区| 日本三级在线播放完整版| 国产欧美日韩精品专区| 99久久婷婷这里只有精品| 亚洲欧美偷拍另类| 亚洲欧美综合另类在线卡通| 一级特黄录像免费看| 成人444kkkk在线观看| 午夜视频一区二区在线观看| 国产精品国三级国产av| 9久草视频在线视频精品| 成人精品免费在线观看| 亚洲色图15p| 狠狠久久伊人中文字幕| 91九色国产ts另类人妖| 国产成人午夜精品5599 | free性欧美hd另类精品| 亚洲xxx大片| 国产亚洲高清视频| av手机在线播放| 欧美一级黄色大片| 超碰在线cao| 亚洲aⅴ天堂av在线电影软件| 狠狠久久亚洲欧美| 免费一级特黄特色大片| 日韩精品亚洲元码| 成人午夜一级| 美女av免费观看| 91蜜桃网址入口| 亚洲一区 中文字幕| 久久99热这里只有精品国产| 欧美18免费视频| 亚洲欧洲日本精品| 亚洲国产wwwccc36天堂| 九色在线观看| 91成人在线看| 久久在线精品| 久久中文字幕在线观看| 亚洲天堂男人天堂女人天堂| 久久综合给合| 无码无遮挡又大又爽又黄的视频| 成人免费视频在线观看| 手机av在线免费观看| 国产欧美精品日韩精品| 国产欧美一区二区三区国产幕精品| 国产成人一区二区在线观看| 日韩精品一区二区三区中文精品| 欧美xx视频| 日本wwwcom| 国产精品网站在线| 四虎永久在线精品免费网址| 国产欧美一区二区三区久久| 亚洲精品社区| 强行糟蹋人妻hd中文| 国产一区二区黑人欧美xxxx|