如何在承诺中使用React错误边界

时间:2020-03-13 11:14:19

标签: javascript reactjs promise react-router react-hooks

我正在尝试为React应用程序中的任何未处理的异常实现通用错误页面。但是,似乎错误边界不适用于诸如API操作之类的承诺引发的异常。我知道我可以在组件级别捕获异常,然后在render方法中将其重新抛出。但这是我想避免的样板。如何在承诺中使用错误边界?

我正在使用带有钩子和react-router的最新React进行导航。

1 个答案:

答案 0 :(得分:1)

您可以通过创建一个HOC来实现,该HOC将带有两个参数,第一个是组件,第二个是promise。它将返回响应并加载到道具中。请找到下面的代码以供参考。

HOC

import React, { Component } from "react";
function withErrorBoundary(WrappedComponent, Api) {
  return class ErrorBoundary extends Component {
    constructor(props) {
      super(props);
      this.state = { hasError: false, response: null, loading: false };
    }
    async componentDidMount() {
      try {
        this.setState({
          loading: true
        });
        const response = await Api;

        this.setState({
          loading: false,
          response
        });
        console.log("response", response, Api);
      } catch (error) {
        // throw error here
        this.setState({
          loading: false
        });
      }
    }
    static getDerivedStateFromError(error) {
      // Update state so the next render will show the fallback UI.
      return { hasError: true };
    }

    componentDidCatch(error, errorInfo) {
      // You can also log the error to an error reporting service
    }

    render() {
      if (this.state.hasError) {
        // You can render any custom fallback UI
        return <h1>Something went wrong.</h1>;
      }

      return (
        <WrappedComponent
          response={this.state.response}
          loading={this.state.loading}
          {...this.props}
        />
      );
    }
  };
}
export default withErrorBoundary;

如何使用HOC

import ReactDOM from "react-dom";
import React, { Component } from "react";
import withErrorBoundary from "./Error";

class Todo extends Component {
  render() {
    console.log("this.props.response", this.props.response);
    console.log("this.props.loading", this.props.loading);
    return <div>hello</div>;
  }
}
const Comp = withErrorBoundary(
  Todo,
  fetch("https://jsonplaceholder.typicode.com/todos/1").then(response =>
    response.json()
  )
);

ReactDOM.render(<Comp />, document.getElementById("root"));

请检查codesandbox的引用