[React] 수도 없이 호출하는 API, 깔끔한 관리법 알아보기

2023. 8. 17. 01:37_Web/React

728x90

문제상황

프론트엔드라면 서버를 통해 API를 호출하면서 렌더링 문제를 마주하게 된다. useEffect와 useState를 통해 데이터를 설정해놔도 다시 호출하면서 다시 빈 데이터가 등록되거나 데이터가 사라지고 실시간 연동이 안되는 등 너무나도 코드가 지저분해지는 문제가 발생했다.

 

따라서 깔끔하게 API를 관리하는 방법의 필요성을 느꼈다. 특히 리액트는 컴포넌트별로 관리하기 때문에 개발을 하다보면 내부의 컴포넌트에 API를 호출하면서 중복호출 되는 경우가 생긴다. 깔끔하게 코딩하는 방법에 대해 알아보자.

 


아래의 글에서 API 요청 관리를 관리하는 사례가 적혀있다. 아래를 참고하여 작성하였다.

 

https://github.com/Ubermensch0608/organize-api-requests

 

GitHub - Ubermensch0608/organize-api-requests: 프론트엔드 API요청 관리 사례를 구현한 저장소입니다

프론트엔드 API요청 관리 사례를 구현한 저장소입니다. Contribute to Ubermensch0608/organize-api-requests development by creating an account on GitHub.

github.com

 

create를 이용하여 인스턴스를 생성하고 이를 호출하는 방법을 적용하기로 했다.

 

인스턴스를 생성하는 방법

    const instance = axios.create({baseURL: "/booking",
      withCredentials: true,
      });

프록시를 적용하였기에 전체 주소를 작성하지 않아도 된다. baseURL: 에 서버에 호출하는 주소를 적고, withCredential을 통해 서로 다른 도메인에 요청을 보낼때 credential 정보를 담아서 보낼지를 결정한다. 쿠키를 사용하거나, 헤더이 Authorization 항목이 있다면 true로 허용해서 cors 문제를 해결할 수 있다.

 

재사용 request 함수 만들기

이 방법을 적용하도록 했다. api 라는 컴포넌트를 따로 만들어 import로 편하게 가져오는 방법을 택했다.

 

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/async_function

 

async function - JavaScript | MDN

async function 선언은 AsyncFunction객체를 반환하는 하나의 비동기 함수를 정의합니다. 비동기 함수는 이벤트 루프를 통해 비동기적으로 작동하는 함수로, 암시적으로 Promise를 사용하여 결과를 반환

developer.mozilla.org

 

윗 문서에서 async 와 await의 사용법을 알 수 있다. 함수의 실행을 일시중지하고 promise의 해결을 기다린다음 async 실행을 시작한다. async 함수는 항상 promise를 반환하므로 명시적으로 promise가 아니라면 암묵적으로 promise를 감싼다. 따라서 then을 써야 promise 객체를 사용하지 않고 편하게 작업이 가능하다.

 

규칙으로 src/apis 폴더 내에 api 모듈을 만든다.

api.jsx

import React, { useEffect, useState } from "react";
import axios from "axios";

const JsonBookingResource = {
  instance: axios.create({
    baseURL: "/",
    withCredentials: true,
  }),
  fetchBooking: async () => {
    const response = await JsonBookingResource.instance.get("/booking");
    return response.data;
  },

  fetchBookingId: async (number) => {
    const response = await JsonBookingResource.instance.get(
      `/booking/${number}`
    );
    return response.data;
  },

  fetchBookingAry: async () => {
    const response = await JsonBookingResource.instance.get("/booking/");
    return response.data.content;
  },

  fetchBookingPassAry: async (number) => {
    const response = await JsonBookingResource.instance.get(
      `/booking?pass=${number}`
    );
    return response.data.content;
  },

  fetchBookingUserAry: async (number) => {
    const response = await JsonBookingResource.instance.get(
      `/booking?user=${number}`
    );
    return response.data.content;
  },
};

export default JsonBookingResource;

 

 

사용할 때 컴포넌트

console.log("bookingCheck");
const bookingData = await JsonBookingResource.fetchBooking();
const bookingDataArray = await JsonBookingResource.fetchBookingAry();
console.log("Booking Data:", bookingData);
console.log("Booking Array:", bookingDataArray);


  useEffect(() => {
    setBookingDataAry(bookingDataArray);
  }, []);

 

 

 

"들어온 bookingData"는 다른 컴포넌트에서 데이터를 가져온 것이고 위 코드 내용이 깔끔하게 적용됨을 확인했다.