【问题标题】:React 16 - error handling for event handlersReact 16 - 事件处理程序的错误处理
【发布时间】:2021-11-24 21:38:00
【问题描述】:

我正在将我们的应用程序从 react 15.4 迁移到 react 16。 我们正在使用 react 的新 errorBonudries,这很棒,但它有一个主要问题 - 错误边界没有捕获事件和异步操作,我需要捕获并记录它们。

我发现的解决方法是使用 window.onerror,但看起来反应“吞下了”真正的错误细节,因为没有将有关错误的真实数据发送到事件。

对于这种类型的处理是否有任何建议,其中不包括对我们正在编写的每个事件块使用 try/catch?

谢谢!

【问题讨论】:

  • 一个演示这种情况的代码示例会有所帮助

标签: reactjs


【解决方案1】:

对于这种类型的处理有什么建议吗? 包括对我们正在编写的每个事件块使用 try/catch 吗?

简而言之,不行。您必须使用try/catch 块。

这是因为事件处理程序(和其他异步操作)是异步的,它们不会在与错误边界的render 相同的事件循环迭代上运行。
所以试图实现你在这里的要求就像你写了这样的东西:

try {
  setTimeout(() => {
    throw new Error('my error outside the event loop')
  }, 0)
} catch (err) {
  console.log('error catched!', err)
}

因此您需要同步渲染和 async 操作(在这种情况下为事件处理程序),一种方法是使用 setStatetry/catch 块。
您尝试代码并在捕获时将错误存储在state 中,这将导致重新渲染,然后您可以有条件地渲染错误或收听此更改并记录一些内容。但这种方法远非方便。

【讨论】:

  • 但是window.on 错误呢?发生错误时触发此事件,但不获取任何参数。这是为什么呢?
【解决方案2】:

我仍然不确定这是否是一个好方法,但我正在使用这个钩子来确保将回调中发生的任何异常转发到错误边界:

/**
 * Like useCallback(), but any sync or async exceptions are caught and synchronously rethrown by the component so
 * that they can be caught by the error boundary.
 */
export function useCatchingCallback<T extends (...args: any[]) => any>(callback: T, deps: DependencyList): T {
    const [error, setError] = useState<Error>();

    if (error) {
        throw error;
    }

    // eslint-disable-next-line react-hooks/exhaustive-deps
    return useCallback(((...args: any) => {
        try {
            const result = callback(...args);
            Promise.resolve(result).catch((err) => {
                setError(err);
            });
            return result;
        } catch (err: any) {
            setError(err);
            throw err;
        }
    }) as any, deps);
}

【讨论】:

    猜你喜欢
    • 2018-01-25
    • 2020-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-15
    • 1970-01-01
    • 2016-08-18
    相关资源
    最近更新 更多