Axios와 async/await

2025. 4. 16. 17:22·React

Axios와 async/await를 활용한 비동기 통신 정리

 Axios란?

Axios는 Node.js와 브라우저 모두에서 사용할 수 있는 Promise 기반의 HTTP 클라이언트
동일한 코드로 브라우저와 Node.js 환경에서 모두 작동할 수 있는 동형(isomorphic) 라이브러리
  • 서버 사이드에서는 Node.js의 http 모듈을 사용
  • 클라이언트(브라우저)에서는 XMLHttpRequest를 이용해 요청

설치 방법

npm install axios

동기(Synchronous) vs 비동기(Asynchronous)

프로그래밍에서는 작업이 실행되는 방식에 따라 **동기(Sync)**와 **비동기(Async)**로 나눌 수 있습니다.

 동기(Synchronous)

  • 순차적으로 작업이 실행
  • 이전 작업이 끝나야 다음 작업이 실행
  • setState 호출 → 이전 상태 업데이트가 완료되어야 다음 로직이 실행
console.log("1");
console.log("2");
console.log("3");
// 출력: 1 → 2 → 3 (순차적 실행)

비동기(Asynchronous)

  • 작업이 완료되지 않아도 다음 코드가 실행
  • axios와 같은 HTTP 요청, setTimeout 등이 대표적
console.log("1");
setTimeout(() => console.log("2"), 1000);
console.log("3");
// 출력: 1 → 3 → 2 (비동기 실행)

주의할 점

axios 같은 비동기 요청은 응답이 도착하기 전에 다음 코드가 실행될 수 있어 의도와 다른 결과가 발생 가능성 ⬆️
이를 해결하기 위해 사용하는 것이 바로 async/await 문법

 


기본적인 Axios 사용법 (Promise 방식)

비동기적으로 데이터 요청 

<script>
  const API_BASE_URL = "http://~:8080/eureka/book";

  function fetchData() {
    axios
      .get(API_BASE_URL) // 비동기 요청
      .then((response) => {
        // 요청이 완료된 후 실행됨
        const books = response.data.books;
        const result = document.getElementById("result");

        if (!Array.isArray(books) || books.length === 0) {
          result.innerHTML = "<h1>도서 정보가 없습니다.</h1>";
          return;
        }

        const html = books
          .map((book) => `<div class='book'>${JSON.stringify(book)}</div>`)
          .join();
        result.innerHTML = html;
      })
      .catch((error) => {
        // 에러 처리
        console.log(error);
        result.innerHTML = "<h1>오류발생</h1>";
      });
  }
</script>

특징

  • .then()으로 요청 완료 후 결과 처리
  • .catch()로 에러 처리
  • 단점: 중첩되면 콜백 지옥처럼 보일 수 있고, 가독성이 떨어짐

async/await 문법으로 더 깔끔하게!

async/await을 활용한 동일 기능

<script>
  async function fetchData() {
    const resultEl = document.getElementById("result");
    const API_BASE_URL = "~0/eureka/book";

    resultEl.innerHTML = "로딩 중...";

    try {
      //  await: axios 응답이 완료될 때까지 기다림
      const response = await axios.get(API_BASE_URL);
      const books = response.data.books;

      if (!Array.isArray(books) || books.length === 0) {
        resultEl.innerHTML = "<h1>도서 정보가 없습니다.</h1>";
        return;
      }

      const html = books
        .map((book) => `<div class='book'>${JSON.stringify(book)}</div>`)
        .join();
      resultEl.innerHTML = html;
    } catch (error) {
      // 에러는 try-catch로 처리
      console.error(error);
      resultEl.textContent = "오류 발생: " + error;
    }
  }
</script>

특징 

  • await는 해당 비동기 작업이 완료될 때까지 기다린다
  • try/catch 문으로 에러 처리가 더 명확하고 직관적

비동기 함수는 useCallback / useEffect와 함께!

: React에서는 비동기 함수를 컴포넌트에서 사용할 때 useCallback, useEffect 등과 함께 사용

const searchAllBooks = useCallback(async () => {
  // 비동기 요청 코드
}, []);

 

=> 리렌더링마다 함수를 새로 만들지 않도록 useCallback을 사용

처음 마운트 시 API 요청 useEffect 언제 실행할지 제어 (의존성 배열로)
버튼 클릭 시 API 요청 useCallback 함수 재생성 방지, 성능 최적화
렌더링 중 비동기 호출 방지 useEffect or useCallback React 렌더링 규칙 지키기 위해

 

배열 형태의미

[] 딱 한 번만 실행 (처음 마운트 시)
[a] a가 바뀔 때마다 실행 or 재생성
[a, b] a 또는 b가 바뀔 때마다 실행 or 재생성

공통 설정이 반복될 때 – Axios 인스턴스 만들기

import axios from "axios";

const BASE_URL = "http://~.8080/eureka/";

// 공통 설정을 포함한 axios 인스턴스
function localAxios() {
  const instance = axios.create({
    baseURL: BASE_URL,
    headers: {
      "Content-Type": "application/json;charset=utf-8",
    },
  });
  return instance;
}

export { localAxios };

 

const axios = localAxios();

 

 

=> localAxios()를 통해 만든 인스턴스를 사용


공통 에러 핸들링 함수로 추출하기

=> 공통 로직은 분리하고, UI와 비즈니스 로직은 각각 나눠서 관리!!!

 

비슷한 패턴의 try/catch 구문을 반복적으로 작성하는 대신 에러 핸들링 로직을 공통화
export const handleApi = async <T>(fn: () => Promise<T>) => {
  try {
    const data = await fn();
    return { data, error: null };
  } catch (error) {
    let msg = "";
    if (error instanceof Error) {
      msg = error.message;
    } else {
      msg = "오류가 발생했습니다.";
    }
    return { data: null, error: msg };
  }
};

 

 

 => handleApi 유틸 함수를 이용하면, 비동기 데이터 요청을 더욱 깔끔하게 관리

const loadBooks = useCallback(
  async (params: BookSearchParams = {}) => {
    setLoading(true); //  로딩 상태 true로 설정

    const { data, error } = await handleApi(() => searchAllBooks(params));
    //  handleApi를 통해 에러와 데이터를 동시에 받아옴

    if (error) {
      setError(error); //  에러 발생 시 에러 상태 업데이트
    } else if (data) {
      setBook(data); //  정상적으로 데이터가 올 경우 상태에 저장
    }

    setLoading(false); //  로딩 완료 처리
  },
  []
);

 

 

'React' 카테고리의 다른 글

Context 알아보기  (0) 2025.04.22
TanStack Query (React Query) 알아보기  (0) 2025.04.21
React & Next.js 활용해보기 / CSR vs SSR  (1) 2025.04.14
React TypeScript 활용해보기  (1) 2025.04.11
SCSS와 SASS: 효율적인 CSS 전처리기 사용법  (0) 2025.04.08
'React' 카테고리의 다른 글
  • Context 알아보기
  • TanStack Query (React Query) 알아보기
  • React & Next.js 활용해보기 / CSR vs SSR
  • React TypeScript 활용해보기
startfront
startfront
startfront 님의 블로그 입니다.
  • startfront
    startfront 님의 블로그
    startfront
  • 전체
    오늘
    어제
    • 분류 전체보기 (42)
      • 프로젝트 (5)
        • 프로젝트 해보기 (1)
        • 디자인 알아보기 (2)
        • 프로젝트의 기본 (2)
      • 백엔드의 이해 (4)
      • React (14)
      • 프론트엔드 기본 (2)
        • Html (1)
        • Css (0)
        • JavaScript (1)
      • Cs기본지식 (14)
        • 알고리즘 (8)
        • 데이터베이스 (6)
      • Java (3)
        • Java의 이해 (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
startfront
Axios와 async/await
상단으로

티스토리툴바