React 错误边界
- 部分 UI 的 JavaScript 错误不应该导致整个应用崩溃,为了解决这个问题,React 16 引入了一个新的概念 —— 错误边界。
- 错误边界可以捕获发生在整个子组件树的渲染期间、生命周期方法以及构造函数中的错误。
一个 class 组件中定义了 static getDerivedStateFromError() 或 componentDidCatch() 这两个生命周期方法中的任意一个(或两个)时,那么它就变成一个错误边界。
当抛出错误后,请使用 static getDerivedStateFromError() 渲染备用 UI ,使用 componentDidCatch() 打印错误信息
错误边界无法捕获到的场景
- 时间处理
- 异步代码
- 服务器渲染
- 它自身抛出的错误(并非它的子组件)
使用场景
任意子组件树的渲染方法 render() 和所有生命周期方法中的错误。
代码
以下使用Ts编写错误边界组件
// 错误边界组件
import React, { Component, ReactNode } from 'react'
// 错误边界只能使用class方式创建组件
type FallbackRender = (props:{error:Error | null}) => React.ReactElement
export default class ErrorBoundary extends React.Component<React.PropsWithChildren<{fallbackRender:FallbackRender}>,{error:Error | null}> {
state ={error:null}
// 当子组件抛出异常,这里会接收到error并修改state中的error
static getDerivedStateFromError(error:Error){
return {error}
}
render(){
const {error} = this.state
const {children,fallbackRender} = this.props
if(error){
return fallbackRender({error})
}
return children
}
}
function App() {
const {user} = useAuth()
return (
<div className="App">
<ErrorBoundary fallbackRender={FullPageErrorFallback}>
{user ? <AuthenticatedApp/> : <UnauthenticatedApp/>}
</ErrorBoundary>
</div>
);
}
export const FullPageErrorFallback = ({error}:{error:Error | null}) => {
return(
<FullPage>
<Typography.Text type={"danger"}>{error?.message}</Typography.Text>
</FullPage>
)
}
React.Component的泛型
class React.Component<P = {}, S = {}, SS = any>
首先要对传入的props 进行类型规范
参数:
children 传入的子组件fullbackRender
type FallbackRender = (props:{error:Error | null}) => React.ReactElement
ReactNode与ReactElement的关系
type ReactNode = ReactElement | string | number | ReactFragment | ReactPortal | boolean | null | undefined;
ReactElement 是ReactNode 联合类型中的一种类型(可以理解为子集)
- props.children是ReactNode类型
- class组件render返回的是ReactNode类型
- function组件返回的是ReactElement类型
export default class ErrorBoundary extends React.Component<{children:ReactNode,fallbackRender:FallbackRender},{error:Error | null}> {
...
}
React.PropsWithChildren
使用这个React提供的泛型,可以减少对children 数据类型的说明
type React.PropsWithChildren<P> = P & {
children?: React.ReactNode;
}
解析:
定义一个React.PropsWithChildren 类型,传入一个泛型,泛型和{children?: React.ReactNode;} 是& 的关系
& 的关系就类似于Object.asign() ——将两个对象合并
|