MST

星途 面试题库

面试题:React中错误边界如何捕获子组件错误并与全局状态管理关联

在React中,错误边界用于捕获其子组件树中的JavaScript错误。请阐述如何创建一个错误边界组件,并且说明怎样将捕获到的错误信息传递到使用Redux进行全局状态管理的store中,假设你已经配置好了Redux环境。
39.9万 热度难度
前端开发React

知识考点

AI 面试

面试题答案

一键面试

创建错误边界组件

  1. 类组件方式
    • 在React中,错误边界是一个类组件,它定义了componentDidCatch生命周期方法。
    import React, { Component } from'react';
    
    class ErrorBoundary extends Component {
      constructor(props) {
        super(props);
        this.state = {
          hasError: false,
          errorMessage: ''
        };
      }
    
      componentDidCatch(error, errorInfo) {
        // 记录错误信息,这里可以发送到日志服务等
        console.log('Error caught:', error, errorInfo);
        this.setState({
          hasError: true,
          errorMessage: error.message
        });
      }
    
      render() {
        if (this.state.hasError) {
          // 可以自定义错误展示界面
          return <div>An error occurred: {this.state.errorMessage}</div>;
        }
        return this.props.children;
      }
    }
    
    export default ErrorBoundary;
    
  2. 使用React 16.6+ 的新语法
    • 也可以使用static getDerivedStateFromErrorcomponentDidCatch组合来实现。
    import React from'react';
    
    class ErrorBoundary extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          hasError: false,
          errorMessage: ''
        };
      }
    
      static getDerivedStateFromError(error) {
        // 更新state使组件进入错误状态
        return { hasError: true, errorMessage: error.message };
      }
    
      componentDidCatch(error, errorInfo) {
        // 同样可以记录错误信息
        console.log('Error caught:', error, errorInfo);
      }
    
      render() {
        if (this.state.hasError) {
          return <div>An error occurred: {this.state.errorMessage}</div>;
        }
        return this.props.children;
      }
    }
    
    export default ErrorBoundary;
    

将错误信息传递到Redux store中

  1. componentDidCatch中使用dispatch
    • 假设已经通过connect或者useSelectoruseDispatch配置好了Redux环境。
    • 首先,从react - redux中导入useDispatch(对于函数组件)或者在类组件中通过connect获取dispatch
    • 函数组件示例
    import React from'react';
    import { useDispatch } from'react - redux';
    import { setError } from '../actions/errorActions';
    
    const ErrorBoundary = () => {
      const dispatch = useDispatch();
      const [hasError, setHasError] = React.useState(false);
      const [errorMessage, setErrorMessage] = React.useState('');
    
      React.useEffect(() => {
        if (hasError) {
          dispatch(setError(errorMessage));
        }
      }, [hasError, errorMessage, dispatch]);
    
      const errorHandler = (error, errorInfo) => {
        console.log('Error caught:', error, errorInfo);
        setHasError(true);
        setErrorMessage(error.message);
      };
    
      return (
        <React.ErrorBoundary onError={errorHandler}>
          {props.children}
        </React.ErrorBoundary>
      );
    };
    
    export default ErrorBoundary;
    
    • 类组件示例
    import React, { Component } from'react';
    import { connect } from'react - redux';
    import { setError } from '../actions/errorActions';
    
    class ErrorBoundary extends Component {
      constructor(props) {
        super(props);
        this.state = {
          hasError: false,
          errorMessage: ''
        };
      }
    
      componentDidCatch(error, errorInfo) {
        console.log('Error caught:', error, errorInfo);
        this.setState({
          hasError: true,
          errorMessage: error.message
        });
        this.props.setError(error.message);
      }
    
      render() {
        if (this.state.hasError) {
          return <div>An error occurred: {this.state.errorMessage}</div>;
        }
        return this.props.children;
      }
    }
    
    const mapDispatchToProps = dispatch => ({
      setError: errorMessage => dispatch(setError(errorMessage))
    });
    
    export default connect(null, mapDispatchToProps)(ErrorBoundary);
    
  2. 定义Redux action和reducer
    • action示例(errorActions.js
    const SET_ERROR ='SET_ERROR';
    
    export const setError = errorMessage => ({
      type: SET_ERROR,
      payload: errorMessage
    });
    
    • reducer示例(errorReducer.js
    const initialState = {
      error: null
    };
    
    const errorReducer = (state = initialState, action) => {
      switch (action.type) {
        case 'SET_ERROR':
          return {
           ...state,
            error: action.payload
          };
        default:
          return state;
      }
    };
    
    export default errorReducer;
    
    • 然后在Redux的combineReducers中添加这个errorReducer
    import { combineReducers } from'redux';
    import errorReducer from './errorReducer';
    
    const rootReducer = combineReducers({
      error: errorReducer
    });
    
    export default rootReducer;