一般每个页面都会处于这三种状态中的一种:
- 加载数据中
- 发生错误
- 正常页面渲染
因此,定义一个统一的处理方法是非常有用的。
以前有一种处理错误的做法是统一在接口层处理,只是这种处理方式有一定的局限性:它只是针对接口,不能处理页面渲染过程中发生的错误;对某些特殊情况也需要额外的处理(比如有些页面对接口的错误希望不处理)。
这里介绍的一种小技巧是根据React的特性写的一个组件PreProcessor
。在PreProcessor
组件中 - 设定默认的数据加载处理方式;
- 设定默认的错误处理方式;
- 正常渲染页面,并捕捉页面中发生的错误.
用法
import PreProcessor from '@/components/PreProcessor'
<PreProcessor
loading={isLoading}
error={hasError}>
{renderContent}
</PreProcessor>
PreProcessor
的children
支持两种类型,一种是React.ReactElement
; 另一种是RenderFunction
, 这种会延迟生成ReactElement对象直到不处于loading和error状态下。
实现源码
import React, { ReactElement } from 'react'
import { isFunction } from '@/utils/utils'
import PageLoading from '../PageLoading'
import DefaultError from '../DefaultError'
type RenderFunction = () => React.ReactElement
type BooleanFunction = () => boolean
interface PreProcessorProps {
error?: boolean | BooleanFunction
loading?: boolean | BooleanFunction
children: React.ReactElement | RenderFunction
}
const PreProcessor: React.FC<PreProcessorProps> = ({
error = false,
loading = false,
children
}) => {
try {
const errorValue = isFunction(error) ? (error as BooleanFunction)() : error
if (errorValue) {
return <DefaultError />
}
const loadingValue = isFunction(loading)
? (loading as BooleanFunction)()
: loading
if (loadingValue) {
return <PageLoading />
}
if (isFunction(children)) {
return (children as RenderFunction)()
}
return children as ReactElement
} catch (err) {
console.error(err)
return <DefaultError />
}
}
export default PreProcessor
网友评论