javascript - React ErrorBoundary - 只是无法让它工作

标签 javascript reactjs redux error-handling

抱歉,我知道有人问过这个问题,但我找不到适合我的示例。如果有这么多人为此苦苦挣扎,似乎还不容易理解。

我只需要知道如何以干净、简单的方式捕获 React 中的错误。我正在使用 CRA 2.0/React 16.7。我想要一个操作级别的 try/catch block ,因为这是我的应用中业务逻辑集中的地方。

我阅读了这篇文章并按照描述实现了它,但我的 ErrorBoundary 对象从未捕获到错误。

例子:

import React, { Component } from "react";

class ErrorBoundary extends Component {
    constructor(props) {
        super(props);
        this.state = { hasError: false };
    }

    static getDerivedStateFromError(error) {
        return { hasError: true };
    }

    componentDidCatch(error, info) {
        console.log("ErrorBoundary: ", error);
        console.log("ErrorBoundary: ", info);
    }

    render() {
        if (this.state.hasError) {
            return <h1>Something went wrong.</h1>;
        }
        return this.props.children;
    }
}

export default ErrorBoundary;

我在顶层包装我的路线:

    return (
        <BrowserRouter>
            <ErrorBoundary>
                <div className="main-container">
                    <SideBar />
                    <div className="some-class">
                        <Switch>
                            <Route path="/events" component={Events} />
                            <Route exact path="/" component={Index} />
                        </Switch>
                    </div>
                </div>
            </ErrorBoundary>
        </BrowserRouter>
    );

在上面的“事件”中,我进行了一个 API 调用,它在 API 端引发了 500 错误:

componentDidMount() {
    this.props.getAllEvents();
}

这是 Redux 操作:

export const getAllEvents = () => {
    return async (dispatch, getState) => {
        try {
            let state = getState();
            const result = await get({
                state: state,
                route: "/v1/events"
            });
            dispatch({
                type: GET_EVENTS,
                payload: result
            });
        } catch (e) {
            console.log("Something went wrong at action...");
        }
    };
};

...“get()”只是包装了一个 Axios GET - 没什么特别的。

我在失败的 API 调用控制台中看到 500 错误。我从未在控制台中看到“出现问题...”,来自上面的 catch block ,尽管在调试时该行确实被命中。

“componentDidCatch()”方法永远不会被调用 - “hasError”始终为 false,它始终呈现子项。

如果我删除 API 端点中的 throw block ,一切正常,我得到了我的数据。我只是无法在 UI 级别捕获错误。我在“componentDidMount()”中尝试了 try/catch,我尝试在操作中删除 try/catch block ...行为没有改变。

提前致谢。

最佳答案

正如其他答案正确指出的那样,React 错误边界只会捕获渲染错误。

由于您使用的是 redux,因此您可以为像您这样的情况构建自己的机制:

  1. 每当发生错误时,您都会分派(dispatch)一个带有 error 属性的操作。
  2. reducer 只查找具有 error 属性的操作。它接收操作并在您的状态树中更新“全局错误”状态
  3. 应用范围内的connect包装器组件会看到这种状态变化并显示回退 UI。

例如:
使用 error 属性调度一个 Action :

export const getAllEvents = () => {
    return async (dispatch, getState) => {
        try {
            ...
        } catch (e) {
            dispatch({
                type: ERROR, 
                error: e // dispatch an action that has `error` property
            });
        }
    };
};

reducer 看到它并更新 state.error 部分:

export default function errorReducer(state = null, action) {
  const { type, error } = action;
  if (type === RESET_ERROR_MESSAGE) {  // an action to clear the error
    return null;
  } else if (error) { // any type of action, but contains an `error`
    return error;
  }
  return state;
}

现在您将您的应用包装在一个已连接边界中:

function Wrapper({error}) {
  if(error) return <h1>Something went wrong</h1>;
  return <App/>;
}

export default connect(
  state => ({
    error: state.error,
  })
)(Wrapper);

关于javascript - React ErrorBoundary - 只是无法让它工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54842773/

相关文章:

javascript - React 组件未接收 Redux 存储更新的 props

unit-testing - 无法读取未定义单元测试 enzyme 的属性 'contextTypes'

javascript - 如何将选项从 HTML 推送到 JS 中的对象数组?

javascript - 如何加载 mbox 内容而不插入 dom

javascript 数组 - 用单引号分隔值和值的值

javascript - 无法导入 Antd 单个组件而不搞乱全局样式

php - 如何使用 wp_enqueue_script?

javascript - 如何在 React Native 中监听触摸事件?

javascript - Reactjs(javascript)我怎么看不到列表为空(之前)api被调用

javascript - 警告 : Failed propType: Invalid prop 'component' supplied to 'route'