防止白屏

  • 使用 ESLint 等代码检查工具,将流程标准化
  • 进行 Code Review ,较少业务上的逻辑死循环

白屏这种问题,主要会遇到的几种情况:

  1. 组件内的 JavaScript 错误会导致 React 的内部状态被破坏,并且在下一次渲染时产生可能无法追踪的错误。这些错误基本上是由较早的其他代码(非 React 组件代码)错误引起的,但 React 并没有提供一种在组件中优雅处理这些错误的方式,也无法从错误中恢复。

预防

  • 如果在拼装的过程中出现错误,那直接会导致编译的失败;
  • 但如果在转换的过程中出现错误,就很不容易被发现。比如常见的空值问题,可以通过 ?. 和引入类似 lodash 这样的库

兜底

写一个兜底的高阶组件,防止错误继续上报

export const errorBoundary = (WrappedComponent) => {
	return class Wrap extends Component {
		state = {
			hasError: false,
		};
 
		static getDerivedStateFromError(err) {
			return {
				hasError: true,
 
				err,
			};
		}
 
		componentDidCatch(err: Error, info: React.ErrorInfo) {
			console.log(err, info);
		}
 
		render() {
			return this.state.hasError ? (
				<ErrorDefaultUI error={this.state.error} />
			) : (
				<WrappedComponent {...this.props} />
			);
		}
	};
};

用这个高阶组件拦截报错信息,展示统一的错误页面,也就是 ErrorDefaultUI。使用起来也很简单,直接在原函数上挂上注解就可以了。

npm 包

在兜底策略上,因为考虑到团队内部和我存在一样的问题,就抽取了兜底的公共高阶组件,封装成了 NPM 包供团队内部使用。

从最终的数据来看,预防与治理方案覆盖了团队内 100% 的 React 项目,头三个月兜底组件统计到了日均 10 次的报警信息,其中有 10% 是公司关键业务。那么经过分析与统计,首先是为关键的 UI 组件添加兜底组件进行拦截,然后就是做内部培训,对易错点的代码进行指导,加强 Code Review。后续到现在,线上只收到过 1 次报警。

参考资料