为什么Hook没有ErrorBoundary?
SegmentFault
共 3647字,需浏览 8分钟
·
2022-06-18 01:48
作者:卡颂
简介:《React技术揭秘》作者
来源:SegmentFault 思否社区
大家好,我卡颂。
在很多全面使用Hooks开发的团队,唯一使用ClassComponent的场景就是使用ClassComponent创建ErrorBoundary。
可以说,如果Hooks存在如下两个生命周期函数的替代品,就能全面抛弃ClassComponent了:
getDerivedStateFromError componentDidCatch
ErrorBoundary实现原理
render阶段,即组件render、Diff算法发生的阶段 commit阶段,即渲染DOM、componentDidMount/Update执行的阶段
如何捕获错误
do { try { // render阶段具体的执行流程
workLoop(); break;
} catch (thrownValue) { handleError(root, thrownValue);
}
} while (true);
try { // ...具体执行流程} catch (error) { captureCommitPhaseError(current, nearestMountedAncestor, error);
}
getDerivedStateFromError原理
// 可以这样this.setState(this.state.num + 1)// 也可以这样this.setState(num => num + 1)
getDerivedStateFromError的实现,就借助了this.setState中改变状态的函数 这一特性。 当捕获错误后,即:
对于render阶段,handleError执行后 对于commit阶段,captureCommitPhaseError执行后
this.setState(
getDerivedStateFromError.bind(null, error)
)
componentDidCatch原理
this.setState(newState, () => { // ...回调})
this.setState(this.state, componentDidCatch.bind(this, error))
处理“未捕获”的错误
实现Hooks中的ErrorBoundary
function ErrorBoundary({children}: {children: ReactNode}) { const [errorMsg, updateError] = useState<Error | null>(null); useErrorBoundary((e: Error) => { // 捕获到错误,触发更新
updateError(e);
}) return ( <div>
{errorMsg ? '报错:' + errorMsg.toString() : children} </div>
)
}
useErrorBoundary((e: Error) => { // ...})// 类似useEffect(() => { // ...})
笔者仿照ClassComponent中ErrorBoundary的实现原理与useEffect的实现原理,实现了原生Hooks —— useErrorBoundary。
总结
评论