본문 바로가기
React

React에서 데이터 Fetching하기 (Fetch API)

by 굿센스굿 2024. 12. 11.
반응형

 

React 애플리케이션을 개발할 때, 외부 API로부터 데이터를 가져오는 것은 매우 일반적인 작업입니다. 이를 위해서는 다양한 방법을 사용할 수 있는데, 그중에서 Fetch API는 가장 널리 사용되는 방법 중 하나입니다. Fetch API는 최신 JavaScript 표준에서 제공하는 네트워크 요청을 처리하는 기능으로, 브라우저 내장 API로 HTTP 요청을 보내고 응답을 받을 수 있습니다.

이 글에서는 React에서 Fetch API를 사용하여 데이터를 가져오는 방법을 단계별로 살펴보고, 실제 애플리케이션에서 어떻게 활용할 수 있는지에 대해 자세히 설명하겠습니다.

1. Fetch API란?

Fetch API는 브라우저에서 제공하는 네트워크 요청 API로, 데이터를 비동기적으로 가져오는 데 사용됩니다. Fetch API는 XMLHttpRequest보다 훨씬 간단하고 직관적인 문법을 제공하며, Promise를 기반으로 작동하여 비동기 작업을 효율적으로 처리할 수 있습니다.

fetch() 함수는 기본적으로 두 가지 인수를 받습니다:

  1. URL: 요청할 리소스의 URL
  2. 옵션 객체(선택 사항): 요청 방식, 헤더, 본문 등 추가적인 설정
fetch(url, options)
  .then(response => response.json())  // 응답을 JSON으로 파싱
  .then(data => console.log(data))     // 데이터를 처리
  .catch(error => console.error('Error:', error));  // 에러 처리

2. React에서 Fetch API 사용하기

React에서 데이터를 가져오기 위해 Fetch API를 사용하는 방법을 알아보겠습니다. 기본적으로 React의 컴포넌트가 마운트될 때 fetch를 통해 데이터를 요청하고, 요청이 완료된 후 받은 데이터를 컴포넌트의 상태(state)로 저장하여 화면에 표시합니다.

2.1. useEffect와 useState를 활용한 데이터 Fetching

useEffect 훅을 사용하여 컴포넌트가 처음 렌더링될 때 데이터를 요청하고, useState를 사용하여 받은 데이터를 상태로 저장합니다. 이 과정에서 비동기 작업을 처리해야 하기 때문에 async/await 구문을 사용하는 것이 일반적입니다.

2.2. 기본적인 예제

먼저, 가장 간단한 Fetch API를 사용하여 데이터를 가져오는 예제를 만들어보겠습니다. 여기서는 https://jsonplaceholder.typicode.com/posts에서 게시물 데이터를 가져옵니다.

import React, { useState, useEffect } from 'react';

const PostList = () => {
  // 상태 설정
  const [posts, setPosts] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    // 데이터를 가져오는 비동기 함수
    const fetchData = async () => {
      try {
        const response = await fetch('https://jsonplaceholder.typicode.com/posts');
        if (!response.ok) {
          throw new Error('네트워크 응답이 올바르지 않습니다.');
        }
        const data = await response.json();
        setPosts(data); // 데이터 상태 업데이트
      } catch (error) {
        setError(error.message); // 에러 상태 업데이트
      } finally {
        setLoading(false); // 로딩 상태 종료
      }
    };

    fetchData(); // 데이터 fetch 호출
  }, []);  // 컴포넌트가 처음 렌더링될 때만 실행

  // 로딩 중일 때 표시할 내용
  if (loading) return
Loading...
;

  // 에러가 발생했을 때 표시할 내용
  if (error) return
Error: {error}
;

  return (

게시물 목록

    {posts.map(post => (
  • {post.title}
  • {post.body}
  • ))}
  );
};

export default PostList;

2.3. 코드 설명

  • useState: 데이터를 상태로 관리하기 위해 posts, loading, error를 상태 변수로 설정합니다.
    • posts: API에서 받아온 게시물 데이터를 저장합니다.
    • loading: 데이터가 로딩 중일 때를 추적합니다.
    • error: 데이터 fetch 중 오류가 발생하면 그 메시지를 저장합니다.
  • useEffect: 컴포넌트가 처음 렌더링될 때 데이터를 한 번만 요청하도록 설정합니다. 빈 배열 []을 두 번째 인자로 전달하면, 이 useEffect는 컴포넌트가 마운트될 때만 실행됩니다.
  • fetchData: 데이터를 가져오는 비동기 함수입니다. await fetch(url)을 사용하여 API 요청을 보내고, 응답을 받으면 response.json()을 사용해 JSON 형식으로 파싱하여 posts 상태에 저장합니다. 에러가 발생할 경우에는 setError를 사용하여 에러 메시지를 상태로 관리합니다.
  • if (loading): 데이터 로딩 중일 때 "Loading..." 메시지를 화면에 표시합니다.
  • if (error): 데이터 fetching 중에 에러가 발생하면 에러 메시지를 화면에 표시합니다.
  • posts.map: 데이터가 로딩되고 오류가 없다면, posts 배열을 순회하며 게시물의 제목과 본문을 렌더링합니다.

2.4. async/await 사용 시의 장점

async/await는 Promise 기반의 비동기 코드를 더 읽기 쉽게 만들어 줍니다. 예를 들어, fetch 함수는 기본적으로 Promise를 반환하기 때문에 .then()과 .catch()를 사용하여 처리할 수 있지만, async/await를 사용하면 더 직관적이고 깔끔하게 코드를 작성할 수 있습니다.

// async/await로 작성한 데이터 fetching 예제
const fetchData = async () => {
  try {
    const response = await fetch('https://jsonplaceholder.typicode.com/posts');
    if (!response.ok) {
      throw new Error('네트워크 응답이 올바르지 않습니다.');
    }
    const data = await response.json();
    setPosts(data);
  } catch (error) {
    setError(error.message);
  } finally {
    setLoading(false);
  }
};

위 코드에서 try/catch 문을 사용하여 네트워크 요청 중 발생할 수 있는 오류를 처리하고 있습니다. await를 사용하여 fetch가 끝날 때까지 기다리므로, 코드 흐름이 더 직관적입니다.

3. 에러 처리

데이터 fetch 작업 중에 오류가 발생할 수 있습니다. 예를 들어, 네트워크 연결이 끊어졌거나, 잘못된 URL을 요청했을 때 에러가 발생할 수 있습니다. 이런 오류들을 처리하기 위해 try/catch 문을 사용하는 것이 좋습니다. response.ok를 체크하여 HTTP 응답 상태가 성공적인지 확인하는 것도 중요한 부분입니다.

const fetchData = async () => {
  try {
    const response = await fetch('https://jsonplaceholder.typicode.com/posts');
    if (!response.ok) {
      throw new Error('네트워크 응답이 올바르지 않습니다.');
    }
    const data = await response.json();
    setPosts(data);
  } catch (error) {
    setError('데이터를 가져오는 중 오류가 발생했습니다.');
  } finally {
    setLoading(false);
  }
};

위 예제에서는 response.ok가 false일 경우, 오류를 발생시키고 이를 catch 블록에서 처리하고 있습니다.

4. 데이터 Fetching 최적화

4.1. 요청 취소하기 (Cleanup)

useEffect 훅에서 비동기 작업을 수행할 때, 컴포넌트가 언마운트되거나 다른 요청이 시작될 때 이전 요청을 취소하고, 메모리 누수를 방지하는 것이 중요합니다. 이를 위해 AbortController를 사용할 수 있습니다.

useEffect(() => {
  const controller = new AbortController();
  const signal = controller.signal;

  const fetchData = async () => {
    try {
      const response = await fetch('https://jsonplaceholder.typicode.com/posts', { signal });
      const data = await response.json();
      setPosts(data);
    } catch (error) {
      if (error.name !== 'AbortError') {
        setError('데이터를 가져오는 중 오류가 발생했습니다.');
      }
    }
  };

  fetchData();

  return () => {
    controller.abort();  // 컴포넌트가 언마운트되거나 useEffect가 재실행될 때 요청을 취소
  };
}, []);

AbortController는 요청을 취소할 수 있게 도와주며, fetch 요청에 signal을 전달하여 해당 요청을 취소할 수 있습니다.

5. 결론

React에서 Fetch API를 사용하여 데이터를 가져오는 과정은 매우 간단하고 직관적입니다. useEffect 훅을 사용하여 컴포

반응형