在React中处理Axios错误

Glu*_*ear 8 error-handling reactjs axios

我有一个React组件,它调用一个函数getAllPeople

componentDidMount() {
   getAllPeople().then(response => {
      this.setState(() => ({ people: response.data }));
    });
  } 
Run Code Online (Sandbox Code Playgroud)

getAllPeople在我的api模块中:

export function getAllPeople() {
  return axios
    .get("/api/getAllPeople")
    .then(response => {
      return response.data;
    })
    .catch(error => {
      return error;
    });
}
Run Code Online (Sandbox Code Playgroud)

我认为这是一个非常基本的问题,但是假设我要在根组件(在我的componentDidMount方法中)而不是在api函数中处理错误,该根组件如何知道我的axios调用是否返回错误?即,处理来自axios承诺的错误的最佳方法是什么?

Sag*_*ane 11

使用Promise catch method *处理API错误的更好方法

axios.get(people)
    .then((response) => {
        // Success
    })
    .catch((error) => {
        // Error
        if (error.response) {
            // The request was made and the server responded with a status code
            // that falls out of the range of 2xx
            // console.log(error.response.data);
            // console.log(error.response.status);
            // console.log(error.response.headers);
        } else if (error.request) {
            // The request was made but no response was received
            // `error.request` is an instance of XMLHttpRequest in the 
            // browser and an instance of
            // http.ClientRequest in node.js
            console.log(error.request);
        } else {
            // Something happened in setting up the request that triggered an Error
            console.log('Error', error.message);
        }
        console.log(error.config);
    });
Run Code Online (Sandbox Code Playgroud)


pal*_*alm 8

getAllPeople函数已经从您的axios调用返回数据或错误消息。因此,在中componentDidMount,您需要检查调用的返回值getAllPeople以决定是返回错误还是有效数据。

componentDidMount() {
   getAllPeople().then(response => {
      if(response!=error) //error is the error object you can get from the axios call
         this.setState(() => ({ people: response}));
      else { // your error handling goes here
       }
    });
  } 
Run Code Online (Sandbox Code Playgroud)

如果要从api返回承诺,则不应解析axiosapi中调用返回的承诺。相反,您可以执行以下操作:

export function getAllPeople() {
  return axios.get("/api/getAllPeople");
}
Run Code Online (Sandbox Code Playgroud)

然后您可以解决componentDidMount

componentDidMount() {
   getAllPeople()
   .then(response => {          
         this.setState(() => ({ people: response.data}));
     })
   .catch(error => { // your error handling goes here}
  } 
Run Code Online (Sandbox Code Playgroud)


Yev*_*huk 6

我的建议是使用React的尖端功能。错误边界

这是Dan Abramov使用此功能的一个示例。在这种情况下,您可以使用此错误边界组件包装组件。在axios中捕获错误的特殊之处在于您可以使用 拦截器来捕获API错误。您的错误边界组件可能看起来像

import React, { Component } from 'react';

const errorHandler = (WrappedComponent, axios) => {
  return class EH extends Component {
    state = {
      error: null
    };

    componentDidMount() {
      // Set axios interceptors
      this.requestInterceptor = axios.interceptors.request.use(req => {
        this.setState({ error: null });
        return req;
      });

      this.responseInterceptor = axios.interceptors.response.use(
        res => res,
        error => {
          alert('Error happened');
          this.setState({ error });
        }
      );
    }

    componentWillUnmount() {
      // Remove handlers, so Garbage Collector will get rid of if WrappedComponent will be removed 
      axios.interceptors.request.eject(this.requestInterceptor);
      axios.interceptors.response.eject(this.responseInterceptor);
    }

    render() {
      let renderSection = this.state.error ? <div>Error</div> : <WrappedComponent {...this.props} />
      return renderSection;
    }
  };
};

export default errorHandler;
Run Code Online (Sandbox Code Playgroud)

然后,您可以将传递axios实例的根组件包装在一起

errorHandler(Checkout, api)
Run Code Online (Sandbox Code Playgroud)

结果,您根本不需要考虑组件内部的错误。