破题
第 3 讲,有说到 错误边界 内容:若渲染异常,在无保护措施下,页面白屏。
进阶打怪:会产生什么影响、会造成什么后果 —-> 怎么做、解决方案。
所以这类问题的中心会发生偏移:从 是什么 到 怎么做,即从 解释原理 到 提供方案。
如何评判方案的优劣呢?从三个方面:
1. 解决问题
表达方式上,展现自己解决问题能力,如回答:我在 X 项目中遇到 Y 问题,通过排查 a、b、c 三点后找到问题根源,最后改动项目中 d、e、f 点完成上线修复。
2. 预防问题
表达方式上,展现自己 问题处理 以 预防为主。
讲项目初始化时,做的几条措施预防同类低级错误。
3. 工程化方案
以上两种方案停留在个人层面,缺乏全盘考虑。
工程化通常以标准化为抓手完成降本增效,它涉及到的方向有:
- 模块标准化;
- 流程标准化;
- 代码风格标准化;
- 。。。
通过标准化的方案解决同类型问题。解决过程减少任务因素,引入 自动化 过程,如:代码风格,引入 ESLint 工具。
除了解决自己所遇到的问题,还需有团队贡献,具备团队视野。(自己欠缺)
如何量化成果???项目价值,业绩贡献,都需落到数据支撑。修改 BUG 后,需提供具有参考性的指标。
审题
此题的回答方向:
- 是什么,即阐述现象、原理,在说原理时,需提供相符案例;
- 怎么解决,即从工程化角度,拿出通用方案,并量化结果,给出数据和指标。
是什么
提供出案例。
开发模式下:报错,react-error-overlay;
生成模式下:页面白屏。
官方对现象的解释:组件内的 JavaScript 错误会导致 React 的内部状态被破坏,并且在下一次渲染时产生可能无法追踪的错误。这些错误基本上是由较早的其他代码(非 React 组件代码)错误引起的,但 React 并没有提供一种在组件中优雅处理这些错误的方式,也无法从错误中恢复。
大白话就是,若有 JS 的错误出现在 React 内部渲染层,就会导致整个应用崩溃。现象:将整个界面移除,出现白屏。
怎么做
通用方案
第 3 讲,错误边界 概念,用到了getDerivedStateFromError
、componentDidCatch
两个生命周期函数。用这两种方案来处理,缺乏整体性考虑。
通用方案应该是:从预防、兜底两个角度着手。
预防
预防需知病根在那儿。
分析渲染异常出现的原因:在渲染层,即 render 中 return 后的 JSX,都是在进行数据的 拼装、转换。
- 若在拼装出错,直接导致编译失败;
- 若在转换出错,不易被发现;
前端的渲染数据大多来自后端接口,数据可靠性就是一个非常重要的问题。此问题被称为:null-safety
,空安全。无最优解。
目前解决方案:
- idx (需配置 Babel 插件,社区使用者少);
- ES2020 中的 Optional Chaining(可选操作链符),如:xxx?.yyyy ;
浏览器兼容性,需配置 Babel:"plugins": ["@babel/plugin-proposal-optional-chaining"]
TS v3.7 可直接使用 可选操作链符,无需配置 Babel;
兜底
空安全 的预防方案都足够完善,但还需一个兜底方案,以防万一。
兜底应限制崩溃的层级。错误边界加到哪里,崩溃到此为止,其他组件可正常使用,所以只需给 UI 组件添加错误边界,可用第 5 章节中提到的高阶组件:export const errorBoundary = WrapperComponent => {
return class Wrap extends Component {
state = { hasError: false }
static getDerivedStateFromError(error) {
return {
hasError: true,
error
}
}
componentDidCatch(error: Error, info: React.ErrorInfo) {
// 上报错误。。。
}
render() {
return (
this.state.hasError ? <ErrorDefaultUI error={this.state.error} /> : <WrapperComponent />
)
}
}
}
@errorBoundary
export default class XXX{}
量化结果
评估做得好不好?用数据说话。
- 预防层面,需看空安全方案在项目中的覆盖量,保证团队内项目都将空安全用起来;
- 兜底层面,需看保障方案在项目中的覆盖率,统计兜底页面成功兜底的次数,最后兜底页面展示时,能够及时完成线上报警。
量化工作主要两个方面:覆盖、统计。
覆盖:最简单的方法就是查看package.json
是否引入相关库。如:有的公司代码检测使用统一的工具(sonar,那只需配置文件即可)。若公司未接入,则用最原始方案,写个 Node 脚本,拉取相关仓库代码自行分析,每周产出一个 dashboard 查看使用情况。
答题
React 异常渲染时,若无任何拦截情况下,会出现白屏现象。其原因:在渲染层出现 JS 错误,导致整个应用崩溃。通常这种错误是在 render 中没有控制好空安全,取到空值导致的。
解决方案上,从两个方面入手:预防、兜底。
预防策略上,空安全解决方法,有三个方案:
- 引入外部函数,如:Facebook 的 idx,lodash.get;
- 引入 Babel 插件,使用 ES2020的标准 - 可选链操作符(推荐);
- TS v3.7 版本后,可直接使用 可选链操作符。
兜底策略上,考虑团队内部,则抽取兜底公共高阶组件,封装,发布 NPM 供团队使用;
量化:从最终数据来看,预防和兜底覆盖了团队 100% 的 React 项目,前几个月兜底组件统计到日均 X 次报警信息,其中 xx% 是关键业务。经分析统计,关键的 UI 组件添加兜底组件进行拦截,然后内部培训,对易错点代码指导,走查代码。后续到现在,线上只收到 x 次报警。