MST

星途 面试题库

面试题:React Hooks下实现错误边界时,如何优雅地处理异步操作引发的错误

假设在一个使用React Hooks构建的应用中,有多个异步操作(如fetch数据、调用异步函数等)。当这些异步操作发生错误时,需要通过错误边界统一捕获并处理,同时要避免阻塞其他正常功能的运行。请描述实现这种需求的思路和关键代码要点。
41.7万 热度难度
前端开发React

知识考点

AI 面试

面试题答案

一键面试

思路

  1. 错误边界定义:React 中的错误边界是一种特殊的组件,它可以捕获其后代组件树中 JavaScript 错误,并记录这些错误,展示降级 UI 而不影响整个应用的运行。
  2. 异步操作处理:将异步操作包装在 try...catch 块中,或者使用 Promise.catch 来捕获错误,并通过 setState 等方式将错误信息传递给错误边界。
  3. 错误边界组件实现:创建一个错误边界组件,在其 componentDidCatch 生命周期方法(对于类组件)或 useEffect 结合 useState(对于函数组件使用 React Hooks)来处理捕获到的错误,并渲染相应的错误 UI。

关键代码要点

  1. 函数式错误边界组件(使用 React Hooks)
import React, { useState, useEffect } from'react';

const ErrorBoundary = ({ children }) => {
  const [error, setError] = useState(null);
  const [errorInfo, setErrorInfo] = useState(null);

  useEffect(() => {
    const handleError = (e, errorInfo) => {
      setError(e);
      setErrorInfo(errorInfo);
    };
    window.addEventListener('error', handleError);
    window.addEventListener('unhandledrejection', handleError);
    return () => {
      window.removeEventListener('error', handleError);
      window.removeEventListener('unhandledrejection', handleError);
    };
  }, []);

  if (error) {
    // 这里返回错误 UI
    return (
      <div>
        <h1>Something went wrong!</h1>
        <p>{error.message}</p>
        <details style={{ whiteSpace: 'pre-wrap' }}>
          {errorInfo && (
            <div>
              <p>Stack:</p>
              <p>{errorInfo.stack}</p>
            </div>
          )}
        </details>
      </div>
    );
  }

  return children;
};

export default ErrorBoundary;
  1. 在异步操作中捕获错误并传递给错误边界
import React, { useState, useEffect } from'react';
import ErrorBoundary from './ErrorBoundary';

const MyComponent = () => {
  const [data, setData] = useState(null);

  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await fetch('your-api-url');
        if (!response.ok) {
          throw new Error('Network response was not ok');
        }
        const result = await response.json();
        setData(result);
      } catch (error) {
        // 这里错误会被错误边界捕获
        throw error;
      }
    };
    fetchData();
  }, []);

  return (
    <ErrorBoundary>
      {data? (
        <div>
          {/* 展示数据 */}
        </div>
      ) : (
        <div>Loading...</div>
      )}
    </ErrorBoundary>
  );
};

export default MyComponent;

以上代码中,ErrorBoundary 组件捕获其子组件树中的错误,并渲染错误 UI。MyComponent 中的异步 fetch 操作在发生错误时抛出错误,被 ErrorBoundary 捕获。