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

為什么Hook沒有ErrorBoundary?

開發(fā) 前端
ErrorBoundary?在ClassComponent?中的實現(xiàn)使用了this.setState?的回調(diào)函數(shù)特性,這使得Hooks中要完全實現(xiàn)同樣功能,需要額外開發(fā)成本。

大家好,我卡頌。

在很多全面使用Hooks開發(fā)的團隊,唯一使用ClassComponent的場景就是「使用ClassComponent創(chuàng)建ErrorBoundary」。

可以說,如果Hooks存在如下兩個生命周期函數(shù)的替代品,就能全面拋棄ClassComponent了:

  • getDerivedStateFromError
  • componentDidCatch

那為什么還沒有對標(biāo)的Hook呢?

今天我們從上述兩個生命周期函數(shù)的實現(xiàn)原理,以及要移植到Hook上需要付出的成本來談?wù)撨@個問題。

ErrorBoundary實現(xiàn)原理

ErrorBoundary可以捕獲子孫組件中「React工作流程」內(nèi)的錯誤。

「React工作流程」指:

  • render階段,即「組件render」、「Diff算法」發(fā)生的階段。
  • commit階段,即「渲染DOM」、「componentDidMount/Update執(zhí)行」的階段。

這也是為什么「事件回調(diào)中發(fā)生的錯誤」無法被ErrorBoundary捕獲 —— 事件回調(diào)并不屬于「React工作流程」。

如何捕獲錯誤

「render階段」的整體執(zhí)行流程如下:

do {
try {
// render階段具體的執(zhí)行流程
workLoop();
break;
} catch (thrownValue) {
handleError(root, thrownValue);
}
} while (true);

可以發(fā)現(xiàn),如果「render階段」發(fā)生錯誤,會被捕獲并執(zhí)行handleError方法。

類似的,「commit階段」的整體執(zhí)行流程如下:

try {
// ...具體執(zhí)行流程
} catch (error) {
captureCommitPhaseError(current, nearestMountedAncestor, error);
}

如果「commit階段」發(fā)生錯誤,會被捕獲并執(zhí)行captureCommitPhaseError方法。getDerivedStateFromError原理。

捕獲后的錯誤如何處理呢?

我們知道,ClassComponent中this.setState第一個參數(shù),除了可以接收「新的狀態(tài)」,也能接收「改變狀態(tài)的函數(shù)」作為參數(shù):

// 可以這樣
this.setState(this.state.num + 1)
// 也可以這樣
this.setState(num => num + 1)

getDerivedStateFromError的實現(xiàn),就借助了this.setState中「改變狀態(tài)的函數(shù)」這一特性。

當(dāng)捕獲錯誤后,即:

  • 對于「render階段」,handleError執(zhí)行后。
  • 對于「commit階段」,captureCommitPhaseError執(zhí)行后。

會在ErrorBoundary對應(yīng)組件中觸發(fā)類似如下更新:

this.setState(
getDerivedStateFromError.bind(null, error)
)

這就是為什么getDerivedStateFromError要求開發(fā)者返回「新的state」— 本質(zhì)來說,他就是觸發(fā)一次新的更新。

componentDidCatch原理

再來看另一個ErrorBoundary相關(guān)的生命周期函數(shù)— componentDidCatch。

ClassComponent中this.setState的第二個參數(shù),可以接收「回調(diào)函數(shù)」作為參數(shù):

this.setState(newState, () => {
// ...回調(diào)
})

當(dāng)觸發(fā)的更新渲染到頁面后,回調(diào)會觸發(fā)。

這就是componentDidCatch的實現(xiàn)原理。

當(dāng)捕獲錯誤后,會在ErrorBoundary對應(yīng)組件中觸發(fā)類似如下更新:

this.setState(this.state, componentDidCatch.bind(this, error))

處理“未捕獲”的錯誤

可以發(fā)現(xiàn),「React運行流程」中的錯誤,都已經(jīng)被React自身捕獲了,再交由ErrorBoundary處理。

如果沒有定義ErrorBoundary,這些「被捕獲的錯誤」需要重新拋出,營造「錯誤未被捕獲的感覺」。

那這一步在哪里執(zhí)行呢?

與this.setState類似,ReactDOM.render(element, container[, callback])第三個參數(shù)也能接收「回調(diào)函數(shù)」。

如果開發(fā)者沒有定義ErrorBoundary,那么React最終會在ReactDOM.render的回調(diào)中拋出錯誤。

可以發(fā)現(xiàn),在ClassComponent中ErrorBoundary的實現(xiàn)完全依賴了ClassComponent已有的特性。

而Hooks本身并不存在類似this.setState的回調(diào)特性,所以實現(xiàn)起來會比較復(fù)雜。

實現(xiàn)Hooks中的ErrorBoundary

除了上述談到的阻礙,F(xiàn)unctionComponent與ClassComponent在源碼層面的運行流程也有細節(jié)上的差異,要照搬實現(xiàn)也有一定難度。

如果一定要實現(xiàn),在「最大程度復(fù)用現(xiàn)有基礎(chǔ)設(shè)施」的指導(dǎo)方針下,useErrorBoundary(ErrorBoundary在Hooks中的實現(xiàn))的使用方式應(yīng)該類似如下:

function ErrorBoundary({children}: {children: ReactNode}) {
const [errorMsg, updateError] = useState<Error | null>(null);
useErrorBoundary((e: Error) => {
// 捕獲到錯誤,觸發(fā)更新
updateError(e);
})
return (
<div>
{errorMsg ? '報錯:' + errorMsg.toString() : children}
</div>
)
}

其中useErrorBoundary的觸發(fā)方式類似useEffect:

useErrorBoundary((e: Error) => {
// ...
})
// 類似
useEffect(() => {
// ...
})

筆者仿照ClassComponent中ErrorBoundary的實現(xiàn)原理與useEffect的實現(xiàn)原理,實現(xiàn)了原生Hooks — useErrorBoundary。

感興趣的朋友可以在useErrorBoundary在線示例[1]體驗效果。

總結(jié)

ErrorBoundary在ClassComponent中的實現(xiàn)使用了this.setState的回調(diào)函數(shù)特性,這使得Hooks中要完全實現(xiàn)同樣功能,需要額外開發(fā)成本。

筆者猜測,這是沒有提供對應(yīng)原生Hooks的原因之一。

參考資料

[1]useErrorBoundary在線示例:https://codesandbox.io/s/angry-mountain-xstgj4?file=/src/App.js。

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

2020-07-22 07:55:12

Python開發(fā)函數(shù)

2013-03-18 09:30:18

Lisp

2022-05-22 21:23:10

前端監(jiān)控系統(tǒng)

2022-07-13 15:23:57

Vue fiberreact前端

2018-03-21 10:00:14

混合云爆發(fā)發(fā)生

2015-11-30 19:01:38

樂視生態(tài)

2020-06-01 21:24:50

物聯(lián)網(wǎng)應(yīng)用程序IOT

2020-08-23 11:03:24

Python開發(fā)void

2024-01-03 07:50:09

云計算數(shù)據(jù)中心ITSM

2021-02-01 10:10:55

Svelte框架開發(fā)

2025-09-24 17:05:02

2025-03-21 10:33:22

2017-07-03 10:52:20

深度學(xué)習(xí)人工智能

2016-10-24 14:35:04

2021-07-21 09:35:36

switchbreakJava

2012-08-07 16:46:35

蘋果Apple TV

2024-04-10 09:05:37

2023-06-16 15:52:19

云計算數(shù)據(jù)中心

2015-04-23 10:15:53

AndroidiOS圖片

2019-04-03 15:46:55

中國編程語言
點贊
收藏

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

蜜桃视频在线入口www| 午夜精彩国产免费不卡不顿大片| www.日本在线视频| 久久综合九色欧美综合狠狠| 污污软件在线观看| 国产亚洲欧洲在线| 久久高清免费| 老子影院午夜伦不卡大全| 亚洲综合丁香婷婷六月香| 欧美高清另类hdvideosexjaⅴ| 久久99亚洲热视| 91久久中文| 国产喷水theporn| 日韩免费观看高清完整版| 欧美日韩一本| 99热这里只有精品免费| 色呦呦一区二区三区| 美女久久精品| 一区二区三区久久网| 亚洲成人久久影院| 成人51免费| 一区视频二区视频| 91成人在线精品| 久久精品66| 大片在线观看网站免费收看| 欧美三级日韩三级| 国产中文精品久高清在线不| 国产美女永久无遮挡| 欧美性猛片aaaaaaa做受| 久久综合五月婷婷| 99er在线视频| av伊人久久| 色中文字幕在线观看| 欧美日韩中文字幕在线视频| 成人免费在线电影网| 97久久国产亚洲精品超碰热| 欧美久久久影院| 久久精品播放| 7878视频在线观看| 色综合视频一区中文字幕| 激情综合网最新| 国产亚洲1区2区3区| 91精品亚洲一区在线观看| 欧美老女人另类| 久草视频这里只有精品| 777午夜精品免费视频| 99久久久久久中文字幕一区| 中文字幕免费中文| 久久久久久久久久久网站| 成人免费视频一区| 天堂av中文在线观看| 日本不卡一区| 亚洲an天堂an在线观看| wwwxx欧美| 欧美日韩精品在线一区| 50路60路老熟妇啪啪| 亚洲天堂av在线播放| 日本色综合中文字幕| 麻豆传媒视频在线观看免费| 97久久夜色精品国产九色| 午夜久久久久久| 天天揉久久久久亚洲精品| 亚洲日本一区二区三区在线观看| 国产日韩欧美黄色| 黑人巨大精品欧美一区二区免费| 色男人天堂综合再现| 三级毛片在线免费看| 97久久夜色精品国产九色| 欧亚洲嫩模精品一区三区| 亚洲经典视频在线观看| 欧美18hd| 四虎影院一区二区| 中文字幕亚洲欧美一区二区三区| 成人高清视频免费观看| 欧美一级片网址| 成年人黄色电影| 日本精品视频在线| 亚洲高清视频在线| 欧美激情五月| 国产二区三区在线| 福利网在线观看| 中文在线资源观看视频网站免费不卡 | av女同在线| 亚洲free性xxxx护士hd| 欧美影院一区二区三区| 日韩制服丝袜av| 午夜不卡影院| 日本三级免费观看| 欧美一级片免费在线| 精品久久久久久久久久久久| 亚洲欧美日韩一区在线观看| 忘忧草在线日韩www影院| 精品视频无码一区二区三区| 国产精品久久97| 欧美日韩国产综合视频在线观看| 日本成人中文字幕在线视频| 全球最大av网站久久| 成视频年人免费看黄网站| 91九色视频在线| 精品国精品自拍自在线| av激情综合网| 成人激情开心网| 欧美黑人猛交| 精品久久久久久久无码| 成人春色激情网| 日韩av一区二区在线观看| 中文字幕欧美三区| 91国语精品自产拍| 成人线上视频| 三上悠亚一区二区三区| 欧美日韩一区二区三区在线观看免| 在线观看欧美日韩国产| 亚洲女人的天堂| 日本系列欧美系列| 黄色免费大全亚洲| 麻豆最新免费在线视频| 成人精品视频一区二区| 国产欧美一区二区三区不卡高清| 原创国产精品91| 18禁网站免费无遮挡无码中文| 日本中文字幕高清视频| 久久精品综合| 2019中文亚洲字幕| 视频在线观看你懂的| 国产日韩精品综合网站| 999精品网站| 草裙成人精品一区二区三区| 亚洲精品丝袜日韩| 一区二区三区不卡在线观看| 日韩av在线播放中文字幕| 猫咪成人在线观看| 羞羞污视频在线观看| 99热99在线| 色阁综合av| 免费人成在线不卡| 国产欧美日韩在线一区二区| av男人的天堂在线观看| 午夜影院免费播放| 特级全黄一级毛片| 亚洲天天在线日亚洲洲精| 亚洲国产精品影院| 成人国产亚洲欧美成人综合网 | 91精品视频免费观看| 中文字幕亚洲字幕| 精品视频1区2区3区| 国产精品久久久久婷婷二区次| 日本vs亚洲vs韩国一区三区二区| 香蕉久久精品日日躁夜夜躁| 国产一二三在线| 色视频精品视频在线观看| 欧美一级在线看| 久久久久高清| 国产精品日韩在线观看| 久久精品视频在线观看| 日韩一区二区三区三四区视频在线观看| 亚洲欧洲日产国产综合网| 青青草原综合久久大伊人精品优势| 成人av手机在线观看| 大奶一区二区三区| 男女视频在线| 国产一级片在线播放| 男人艹女人在线观看| 三年中国中文在线观看免费播放| 91午夜在线播放| 2019精品视频| 美日韩精品视频免费看| 美国十次av导航亚洲入口| 狠狠色综合播放一区二区| 国产v日韩v欧美v| 黄色小视频在线免费观看| 四虎永久在线高清国产精品| 青青青青草视频| 水蜜桃一区二区三区| 国产乱码精品一区二区三区日韩精品 | 视频一区视频二区中文| 欧美性xxxxxx少妇| 久久综合入口| 神马电影在线观看| 国产欧美欧洲在线观看| 欧美精品一区二区三区国产精品| 亚洲精品天天看| 亚洲国产第一页| 在线不卡欧美精品一区二区三区| 精品国产91久久久久久| 亚洲成a人片综合在线| 一区二区三区在线免费播放| 国产精品乱码妇女bbbb| 国产农村妇女精品| 国产亚洲一区二区三区四区 | 九色视频网站入口| 色播五月综合网| 免费女人黄页| 女生裸体视频网站免费观看| 爱草在线视频| 性欧美18+| 一级二级三级在线观看| 黄色国产在线| 麻豆传媒视频在线| 丁香花在线观看完整版电影| 美女高潮视频在线看|