codememo

반응에서 Axios 처리 오류

tipmemo 2023. 3. 9. 22:05
반응형

반응에서 Axios 처리 오류

함수를 호출하는 React 컴포넌트가 있습니다.getAllPeople:

componentDidMount() {
   getAllPeople().then(response => {
      this.setState(() => ({ people: response.data }));
    });
  } 

getAllPeople내 안에 있다api모듈:

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

이것은 매우 기본적인 질문이라고 생각합니다만, 루트 컴포넌트의 에러를 처리하고 싶다고 가정하면,componentDidMountmethod)에 없습니다.api기능, 이 루트 컴포넌트는 I가 이 기능을 사용할 수 있는지 여부를 어떻게 알 수 있습니까?axios콜이 오류를 반환합니까?예를 들어, 데이터 센터로부터 발생하는 오류를 처리하는 가장 좋은 방법은 무엇입니까?axios약속하는 거죠?

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);
    });

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
       }
    });
  } 

api에서 약속을 반환하고 싶은 경우 반환된 약속을 해결하지 마십시오.axiosAPI를 호출합니다.대신 다음 작업을 수행할 수 있습니다.

export function getAllPeople() {
  return axios.get("/api/getAllPeople");
}

그러면 다음 시간에 해결할 수 있습니다.componentDidMount.

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

리액트의 최첨단 기능을 사용하는 것이 좋습니다.오류 경계

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;

그런 다음 루트 컴포넌트를 사용하여 Axios 인스턴스를 전달할 수 있습니다.

errorHandler(Checkout, api)

따라서 컴포넌트 내부의 에러는 전혀 생각할 필요가 없습니다.

다음과 같이 설정하기 전에 응답을 확인할 수 있습니다.state뭐랄까...

componentDidMount() {
   getAllPeople().then(response => {
       // check if its actual response or error
        if(error) this.setState(() => ({ error: response }));
        else this.setState(() => ({ people: response}));
    });
  }

그것은 그 사실에 의존합니다.axios는 성공과 실패를 위해 다른 개체를 반환합니다.

Yevheni Herasymchuk의 솔루션은 제가 필요로 하는 것에 매우 가까웠지만, 저는 Hooks와 Redux를 사용할 수 있도록 기능적인 컴포넌트를 갖춘 구현을 목표로 했습니다.

먼저 래퍼를 작성했습니다.

export const http = Axios.create({
    baseURL: "/api",
    timeout: 30000,
});

function ErrorHandler(props) {

useEffect(() => {
    //Request interceptor
    http.interceptors.request.use(function (request) {
        // Do something here with Hooks or something else
        return request;
    });

    //Response interceptor
    http.interceptors.response.use(function (response) {
        if (response.status === 400) {
            // Do something here with Hooks or something else
            return response;
        }
        return response;
    });
}, []);

return props.children;
}

export default ErrorHandler;

그런 다음 공리들이 어떻게 행동하는지 확인하기 위해 필요한 부분을 마무리했습니다.

<ErrorHandler>
  <MainPage/>
</ErrorHandler>

마지막으로 Axios instance(http)를 프로젝트 내 필요한 곳에 Import합니다.

다른 접근법을 원하는 모든 사람에게 도움이 되길 바랍니다.

Yevheni Herasymchuk과 George Code Hub의 답을 조합하여 몇 가지 오류를 수정하고 React 훅에 포팅했습니다.최종 작업 버전은 다음과 같습니다.

// [project-directory]/src/lib/axios.js

import Axios from 'axios';

const axios = Axios.create({
  baseURL: process.env.NEXT_PUBLIC_BACKEND_URL,
  headers: {
    'X-Requested-With': 'XMLHttpRequest',
  },
  withCredentials: true,
});

export default axios;


// [project-directory]/src/components/AxiosErrorHandler.js

import {useEffect} from 'react';
import axios from '@/lib/axios';

const AxiosErrorHandler = ({children}) => {
  useEffect(() => {
    // Request interceptor
    const requestInterceptor = axios.interceptors.request.use((request) => {
      // Do something here with request if you need to
      return request;
    });

    // Response interceptor
    const responseInterceptor = axios.interceptors.response.use((response) => {
      // Handle response here

      return response;
    }, (error) => {
      // Handle errors here
      if (error.response?.status) {
        switch (error.response.status) {
          case 401:
            // Handle Unauthenticated here
            break;
          case 403:
            // Handle Unauthorized here
            break;
          // ... And so on
        }
      }

      return error;
    });

    return () => {
      // Remove handlers here
      axios.interceptors.request.eject(requestInterceptor);
      axios.interceptors.response.eject(responseInterceptor);
    };
  }, []);

  return children;
};

export default AxiosErrorHandler;

사용방법:

// Wrap it around your Layout or any component that you want

return (
  <AxiosErrorHandler>
    <div>Hello from my layout</div>
  </AxiosErrorHandler>
);

언급URL : https://stackoverflow.com/questions/47005457/handling-axios-error-in-react

반응형