javascript - 将 ErrorBoundary 与异步生命周期函数一起使用
问题描述
我想构建一个 React 组件,它异步加载数据componentDidMount
。
这是函数当前的样子(写在 中TypeScript
):
async componentDidMount(): Promise<void> {
try {
const { props: { teamId }, state: { } } = this;
const awaitableData = await UrlHelper.getDataAsync("some-fancy-url");
// ... do something with awaitableData
} catch(e) {
console.log("Some error occured");
throw e;
}
}
-functionrender
返回包装在ErrorBoundary
组件中的标记,该组件已componentDidCatch
实现。但是,当等待的呼叫被拒绝并且我最终进入catch
-block 时,它永远不会被调用/触发。
我在这里想念什么?
解决方案
async
function 是返回 promise 的常规函数的语法糖。函数错误会async
导致 promise 被拒绝。即使拒绝的承诺没有在任何地方处理并导致Uncaught (in promise)
错误,它也不会被错误边界捕获。
正如参考文献所述,
错误边界不会捕获以下错误: <...> 异步代码(例如 setTimeout 或 requestAnimationFrame 回调)
一个解决方案是在出错时更改组件状态并在下一次渲染时处理它。 render
是可以同步重新抛出错误的地方。
一个例子:
state = { error: null };
async componentDidMount() {
try {
await new Promise(resolve => setTimeout(resolve, 2000));
throw new Error('Foo error');
} catch (error) {
this.setState({ error });
}
}
render() {
if (this.state.error) {
throw this.state.error;
}
return (
<p>Foo</p>
);
}
推荐阅读
- java - Selenium Chrome 驱动程序在运行项目时崩溃
- html - 如何在没有垂直滚动的情况下指定屏幕的全高?
- python - 如何在系统托盘中最小化我的 PySimpleGUI 程序,同时保持程序在后台打开?
- php - 如何在 laravel 中输入所有数组并在字段下方显示验证错误
- java - 为什么优化的虚拟调用在热点 jit 程序集中指向相同的地址?
- c++ - 减去整数数组的索引的结果
- mips - 程序一直显示“存储中未对齐的地址:0x100100d2”错误
- django - Django Todo App - 按外键过滤导致 TypeError
- laravel - 在 maatwebsite excel 导出/导入中,我需要插入名称而不是 id
- bash - 在数字列表中添加前导空格?