본문 바로가기
IT 모바일 Gear Up

JS 리액트 Axios 데이터 전송 및 렌더링 방법

by sk2nd 2025. 2. 12.

목차

    JS 리액트 Axios를 활용한 데이터 전송 및 렌더링 방법

    리액트 개발 환경에서 Axios를 사용하면 외부 JSON 데이터나 API로부터 쉽게 데이터를 가져올 수 있습니다. 이번 포스팅에서는 Axios의 설치부터 데이터를 가져와 useStateuseEffect를 활용하여 상태를 관리하고, 데이터를 화면에 렌더링하는 전체적인 과정을 단계별로 알아보겠습니다.

    리액트 프로젝트에서 외부 데이터를 다루는 과정은 크게 라이브러리 설치 → 초기 설정 → 데이터 요청 → 상태 관리 → 렌더링의 순서로 진행됩니다. 각 단계별로 중요한 포인트와 주의 사항을 자세하게 살펴보겠습니다.


    1. Axios 설치 및 초기 설정

    JS 리액트 Axios

    1-1. Axios 설치

    새로운 리액트 프로젝트를 생성한 후, Axios 라이브러리를 설치하는 것이 첫 번째 단계입니다. 터미널에서 아래 명령어를 입력하여 설치할 수 있습니다.

    npm install axios

    위 명령어를 실행하면 node_modules 폴더에 axios가 설치되며, 프로젝트 내에서 사용할 수 있게 됩니다.

    1-2. Axios 임포트

    설치가 완료되면 필요한 파일 상단에 아래와 같이 Axios를 임포트합니다.

    import axios from 'axios';

    이제 Axios를 이용하여 API 호출이나 데이터 요청을 손쉽게 진행할 수 있습니다.


    2. useEffect와 Axios로 데이터 가져오기

    리액트에서 컴포넌트가 화면에 마운트되거나 업데이트될 때 특정 동작을 수행하기 위해 useEffect 훅을 사용합니다. 이번 예제에서는 컴포넌트가 처음 렌더링될 때 외부 API로부터 데이터를 가져오는 방법을 설명합니다.

    2-1. useEffect 기본 구조

    useEffect는 컴포넌트가 렌더링된 후 특정 작업을 수행하기 위해 사용되며, 아래와 같이 작성할 수 있습니다.

    useEffect(() => {
      console.log("컴포넌트가 마운트되었습니다.");
    }, []);

    두 번째 인자인 빈 배열([])은 해당 useEffect가 컴포넌트가 처음 마운트될 때만 실행되도록 보장합니다.

    2-2. Axios를 통한 데이터 요청

    useEffect 내부에서 Axios를 사용하여 데이터를 가져오는 코드는 아래와 같습니다. 이 코드는 API가 정상적으로 동작할 때 응답 데이터(response.data)를 콘솔에 출력하며, 에러가 발생하면 catch 구문에서 “실패함” 메시지를 출력합니다.

    useEffect(() => {
      axios
        .get("https://kku-git.github.io/nff_product/product.json")
        .then((response) => {
          console.log(response.data);
        })
        .catch(() => {
          console.log("실패함");
        });
    }, []);

    이와 같이 useEffect 내부에서 Axios의 get 메소드를 활용하면 컴포넌트가 마운트될 때 외부 JSON 데이터를 가져올 수 있습니다.


    3. useState를 활용한 상태 관리

    데이터를 가져온 후 이를 화면에 표시하기 위해서는 컴포넌트의 상태(state)에 저장하는 것이 좋습니다. 리액트에서는 useState 훅을 사용하여 상태를 관리합니다.

    3-1. 상태 변수 생성

    아래 코드에서는 빈 배열([])을 초기값으로 가지는 items라는 상태 변수를 생성합니다. 이 변수는 외부 API에서 받아온 상품 데이터(배열 형태)를 저장하는 용도로 사용됩니다.

    const [items, setItems] = useState([]);
    • items: 외부 데이터(상품 목록 등)를 담을 변수
    • setItems: items의 상태를 업데이트하기 위한 함수

    상태로 관리하는 이유는 컴포넌트가 다시 렌더링될 때마다 최신 데이터를 반영하기 위함입니다.

    3-2. 데이터 상태 업데이트

    앞서 작성한 useEffect 내부에서 Axios를 사용하여 데이터를 가져온 후, setItems 함수를 이용하여 받아온 데이터를 상태에 저장할 수 있습니다. 예를 들어, 다른 API 엔드포인트(예: neck.json)를 사용한다면 아래와 같이 작성합니다.

    useEffect(() => {
      axios
        .get("https://kku-git.github.io/nff_product/neck.json")
        .then((response) => {
          setItems(response.data);
        })
        .catch(() => {
          console.log("실패함");
        });
    }, []);

    이제 컴포넌트는 외부 API로부터 받아온 데이터를 items 상태에 저장하고, 이 데이터를 활용하여 동적으로 UI를 렌더링할 수 있습니다.


    4. 로딩 처리 및 조건부 렌더링

    데이터를 비동기적으로 가져올 때는 컴포넌트가 처음 렌더링될 때 아직 데이터가 없는 상태일 수 있습니다. 이 경우 데이터 접근 시 undefined 오류가 발생할 수 있으므로, 로딩 상태를 처리하는 로직을 추가하는 것이 좋습니다.

    4-1. 로딩 상태 확인

    items 배열의 길이가 0인 경우, 아직 데이터가 로드되지 않았다고 판단하고 "LOADING..." 메시지를 표시하도록 할 수 있습니다. 조건문을 이용해 아래와 같이 처리합니다.

    if (items.length === 0) {
      return <p>LOADING...</p>;
    }

    이 조건문은 컴포넌트의 렌더링 과정 초기에 데이터를 받아오지 못했을 때 즉시 로딩 상태를 반환하여, 이후 데이터가 로드되면 정상적으로 UI가 렌더링되도록 합니다.

    4-2. 주의할 점

    • 조건부 렌더링의 위치: JSX 내부에서는 if 조건문을 직접 사용할 수 없으므로, 컴포넌트 최상단에 조건을 작성하여 return 문으로 조기 종료하도록 해야 합니다.
    • 데이터 접근 시 안전성: 만약 items가 빈 배열인 상태에서 items[0]와 같이 직접 데이터에 접근하면 undefined 오류가 발생할 수 있으므로 반드시 데이터가 로드된 후에 접근해야 합니다.

    5. map 함수와 동적 렌더링

    외부에서 받아온 데이터는 배열 형태인 경우가 많습니다. 이 데이터를 화면에 여러 개의 컴포넌트로 렌더링하려면 map 함수를 사용하면 편리합니다.

    5-1. map 함수 기본 사용법

    아래 코드는 items 배열을 map 함수로 순회하며 각 항목을 화면에 렌더링하는 예제입니다.

    return (
      <div className="item-container">
        {items.map((item, index) => (
          <div key={index} className="item">
            <div className="overlay-wrap">
              <div className="overlay">
                <p>{item.title}</p> {/* 상품 제목 */}
                <p>{item.price}</p> {/* 상품 가격 */}
              </div>
            </div>
            <img
              src={`https://kku-git.github.io/nff_product/fingers/ring${index + 1}.jpg`}
              alt={`ring ${index + 1}`}
            />
          </div>
        ))}
      </div>
    );

    여기서 몇 가지 중요한 포인트를 짚어보겠습니다.

    • key 속성: React는 리스트 렌더링 시 각 요소에 고유한 key 속성을 요구합니다. 여기서는 index 값을 key로 사용했지만, 가능한 경우 고유한 id 값을 사용하는 것이 좋습니다.
    • 템플릿 리터럴 사용: 이미지의 src 경로에 동적으로 index 값을 삽입하기 위해 백틱(```)과 ${} 구문을 사용합니다. 이로 인해 각 아이템에 대해 서로 다른 이미지가 렌더링됩니다.

    5-2. 동적 렌더링의 장점

    • 유연한 데이터 처리: 데이터가 몇 개든지 상관없이 map 함수를 통해 반복적으로 UI 요소를 생성할 수 있으므로, 하드코딩 없이 유동적인 렌더링이 가능합니다.
    • 가독성과 유지보수성 향상: 데이터 구조가 변경되더라도 map 함수를 사용하는 방식은 코드 수정이 간편하여 유지보수가 용이합니다.

    6. 실제 코드 구현 예제

    지금까지 설명한 내용을 하나의 컴포넌트에 통합해보겠습니다. 아래 예제 코드는 전체적인 데이터 요청부터 상태 업데이트, 조건부 렌더링, 동적 데이터 표시까지 포함한 완성된 예제입니다.

    import React, { useState, useEffect } from 'react';
    import axios from 'axios';
    
    function ProductList() {
      // 초기 상태: 빈 배열
      const [items, setItems] = useState([]);
    
      // 컴포넌트 마운트 시 데이터 요청
      useEffect(() => {
        axios
          .get("https://kku-git.github.io/nff_product/neck.json")
          .then((response) => {
            // 받아온 데이터로 상태 업데이트
            setItems(response.data);
          })
          .catch(() => {
            console.log("데이터를 불러오지 못했습니다.");
          });
      }, []);
    
      // 데이터가 아직 로드되지 않았을 경우 로딩 메시지 표시
      if (items.length === 0) {
        return <p>LOADING...</p>;
      }
    
      return (
        <div className="item-container">
          {items.map((item, index) => (
            <div key={index} className="item">
              <div className="overlay-wrap">
                <div className="overlay">
                  <p>{item.title}</p>
                  <p>{item.price}</p>
                </div>
              </div>
              <img
                src={`https://kku-git.github.io/nff_product/fingers/ring${index + 1}.jpg`}
                alt={`ring ${index + 1}`}
              />
            </div>
          ))}
        </div>
      );
    }
    
    export default ProductList;

    6-1. 코드 설명

    1. 상태 초기화: useState([])를 사용해 items를 빈 배열로 초기화합니다.
    2. 데이터 요청: useEffect 내부에서 Axios의 get 메소드를 사용해 외부 JSON 데이터를 요청합니다.
    3. 상태 업데이트: API 호출이 성공하면 setItems(response.data)를 통해 받아온 데이터를 상태에 저장합니다.
    4. 조건부 렌더링: 데이터가 없을 경우 LOADING... 메시지를 반환하여 사용자에게 로딩 상태를 알려줍니다.
    5. 동적 렌더링: 데이터가 존재하면 items.map을 통해 각 상품 정보를 화면에 렌더링하며, 이미지의 경로는 백틱과 템플릿 리터럴을 이용해 동적으로 생성합니다.

    이와 같은 방식으로 작성된 컴포넌트는 외부 API와 통신하여 실시간 데이터를 가져오고, 이를 기반으로 UI를 구성할 수 있게 해줍니다.


    7. 데이터 관리 및 UI 구성 시 고려 사항

    7-1. 비동기 처리와 에러 핸들링

    Axios를 사용하면 네트워크 지연이나 API 오류 등 비동기 처리 중 발생할 수 있는 여러 상황을 고려해야 합니다. 위 예제에서는 .catch() 구문을 통해 에러가 발생할 경우 콘솔에 메시지를 출력하도록 처리했지만, 실제 서비스에서는 사용자에게 친절한 에러 메시지를 표시하거나 재시도 로직을 구현하는 것이 좋습니다.

    7-2. 로딩 상태 및 사용자 경험

    • 로딩 상태: API 호출이 완료되기 전까지는 데이터를 사용할 수 없으므로, 사용자에게 “LOADING...” 등의 메시지를 통해 데이터 로딩 중임을 명확히 알리는 것이 중요합니다.
    • 조건부 렌더링: 데이터가 없는 상태에서 UI 요소에 접근하면 오류가 발생할 수 있으므로, 반드시 조건부 렌더링을 통해 안전하게 데이터를 처리해야 합니다.

    7-3. 동적 데이터 처리

    리액트의 강점 중 하나는 데이터의 변화에 따라 UI가 자동으로 업데이트된다는 점입니다. 외부 API로부터 데이터를 받아오면 이를 상태에 저장하고, 상태가 변경될 때마다 컴포넌트가 재렌더링되므로, 항상 최신의 데이터를 화면에 표시할 수 있습니다.


    8. 실무 적용 팁

    실제 프로젝트에서는 다음과 같은 추가적인 팁을 고려해볼 수 있습니다.

    • 컴포넌트 분리: 데이터 요청 및 로딩 처리를 별도의 컴포넌트로 분리하여, 재사용성과 유지보수성을 높일 수 있습니다.
    • 에러 경계(Error Boundary): React의 에러 경계 기능을 활용하여, 데이터 요청 중 발생한 예기치 않은 오류에 대비할 수 있습니다.
    • 캐싱 전략: 동일한 API 호출을 반복하지 않도록 캐싱을 도입하거나, SWR(React Hooks 기반 데이터 패칭 라이브러리)와 같은 라이브러리를 활용하는 것도 좋은 방법입니다.
    • 스타일링: CSS-in-JS나 Sass 등을 사용해, 동적으로 생성되는 UI 요소에 대해 일관된 스타일링을 적용할 수 있습니다.

    9. 결론

    이번 포스팅에서는 리액트 프로젝트에서 Axios를 사용하여 외부 API로부터 데이터를 가져오고, 이를 useStateuseEffect로 관리하며, 조건부 렌더링과 map 함수를 통해 동적 UI를 구성하는 방법을 살펴보았습니다. 요약하자면,

    1. Axios 설치 및 임포트
      • npm 명령어로 설치 후, import 구문으로 불러옵니다.
    2. useEffect를 활용한 데이터 요청
      • 컴포넌트 마운트 시 데이터를 가져오고, 성공 시 상태 업데이트, 실패 시 에러 처리를 진행합니다.
    3. useState로 데이터 상태 관리
      • 초기값을 빈 배열로 설정하고, 받아온 데이터를 상태에 저장합니다.
    4. 조건부 렌더링과 로딩 처리
      • 데이터가 아직 없는 경우 로딩 메시지를 표시하여 오류를 방지합니다.
    5. map 함수를 통한 동적 렌더링
      • 받아온 배열 데이터를 map 함수로 순회하며 화면에 렌더링하고, 템플릿 리터럴을 통해 동적 이미지 경로를 생성합니다.

    이와 같은 방법을 사용하면, 사용자 경험을 저해하지 않으면서도 외부 데이터를 유연하게 관리할 수 있습니다. 또한, 에러 처리와 로딩 상태를 적절히 관리함으로써 안정적인 리액트 애플리케이션을 개발할 수 있습니다.

    실제 프로젝트에서는 위와 같은 패턴을 다양한 데이터 요청 상황에 응용할 수 있으며, 더 복잡한 비즈니스 로직이나 상태 관리 라이브러리(Redux, MobX 등)와 연동하는 경우에도 기본적인 데이터 요청과 렌더링 패턴은 동일하게 적용됩니다.

    리액트와 Axios를 처음 접하는 분들이라면, 위 예제를 참고하여 기본적인 데이터 요청 및 렌더링 패턴을 익히고, 이후 프로젝트에 적용해보시기 바랍니다. 또한, 다양한 API와 비동기 통신 패턴을 경험하면서, 사용자 친화적인 로딩 및 에러 처리 로직을 구현하는 연습을 통해 실력을 향상시킬 수 있을 것입니다.


    추가 팁: 코드 확장 및 모듈화

    프로젝트가 커짐에 따라 API 호출이나 데이터 관리를 위한 별도의 모듈을 만드는 것도 좋은 방법입니다. 예를 들어, Axios 인스턴스를 생성하여 공통 설정(기본 URL, 헤더 등)을 적용하고, 이를 여러 컴포넌트에서 재사용할 수 있습니다.

    // api.js
    import axios from 'axios';
    
    const api = axios.create({
      baseURL: "https://kku-git.github.io/nff_product/",
      timeout: 5000, // 요청 타임아웃 설정
    });
    
    // 필요에 따라 인터셉터 추가
    api.interceptors.response.use(
      (response) => response,
      (error) => {
        console.error("API 호출 오류:", error);
        return Promise.reject(error);
      }
    );
    
    export default api;

    위와 같이 모듈을 분리해두면, 각 컴포넌트에서는 단순히 import api from './api'; 후에 api.get('neck.json')과 같이 호출하여 사용할 수 있습니다. 이는 코드의 재사용성을 높이고, 유지보수를 용이하게 만듭니다.


    마무리

    리액트에서 Axios를 활용한 데이터 요청과 상태 관리는 매우 기본적이면서도 강력한 기능입니다. 위에서 설명한 패턴을 잘 이해하고 응용한다면, 여러분은 다양한 외부 API와 연동되는 동적인 웹 애플리케이션을 구현할 수 있습니다. 특히, 데이터의 비동기 처리, 로딩 상태, 에러 핸들링, 동적 렌더링 등은 실무에서 자주 마주치는 문제들이므로 꼼꼼히 익혀두면 좋습니다.

    이번 포스팅이 리액트와 Axios를 활용한 데이터 처리에 대해 깊이 있는 이해를 제공하는 데 도움이 되었기를 바랍니다. 지속적으로 다양한 기능을 시도해보고, 필요에 따라 추가적인 기능(예: 페이징 처리, 필터링 등)을 구현하며 프로젝트에 응용해보세요.


    이상으로 JS 리액트에서 Axios를 사용하여 데이터를 넣고 렌더링하는 방법에 대해 알아보았습니다. 각 단계를 꼼꼼히 따라해 보면서, 프로젝트에 필요한 데이터 처리 로직을 자유롭게 확장해 보시기 바랍니다. Happy Coding!

    반응형

    댓글