React · 2026-02-10

React와 REST API 통합: 에러 처리 및 재시도 전략

React 애플리케이션에서 REST API 에러 처리를 명확히 하고 재시도 전략을 설계하는 방법과 실무 코드 예제 모음

작성일 : 2026-02-10 ㆍ 작성자 : 관리자
post
목차

개요

API 통합은 React 개발에서 가장 빈번한 과제다. 네트워크 실패, 서버 에러, 시간 초과 등 다양한 오류가 발생한다. 안정적인 사용자 경험을 위해서는 에러를 구분하고 적절히 처리하며 필요하면 재시도 전략을 적용해야 한다. 이 글은 초보자도 이해할 수 있도록 react api 에러 처리의 기초부터 fetch retry react 적용법, axios interceptors react 활용 예까지 단계별로 정리한다.

에러 유형과 우선순위

먼저 에러를 분류한다. 분류가 명확해야 적절한 대응을 설계할 수 있다.

주요 분류

  • 네트워크 오류: 인터넷 연결 문제나 DNS 오류
  • HTTP 오류: 4xx(클라이언트), 5xx(서버) 응답
  • 타임아웃: 요청이 지정 시간 내에 완료되지 않음
  • 데이터 오류: 응답 스키마가 예상과 다른 경우

각 유형별로 사용자에게 보여줄 메시지, 자동 재시도 여부, 로깅 대상 등을 결정한다.

재시도 전략의 기본 원칙

재시도는 무조건 좋은 해결책이 아니다. 다음 원칙을 고려한다.

  • 아이덴티파이 가능한 실패에만 재시도: 네트워크 오류나 5xx는 재시도 후보
  • 지수 백오프(Exponential Backoff): 짧은 간격의 연속 호출을 피한다
  • 최대 재시도 횟수 제한: 무한 루프 방지
  • 사용자 제어: 중요한 작업은 사용자에게 재시도 옵션 제공

fetch로 재시도 구현

브라우저 기본 API인 fetch를 사용할 때는 직접 재시도 로직을 작성한다. 아래 예제는 간단한 지수 백오프와 최대 재시도 횟수를 적용한 패턴이다.

async function fetchWithRetry(url, options = {}, retries = 3, backoff = 300) {
  try {
    const controller = new AbortController();
    const id = setTimeout(() => controller.abort(), options.timeout || 10000);
    const res = await fetch(url, { ...options, signal: controller.signal });
    clearTimeout(id);

    if (!res.ok) {
      const isServerError = res.status >= 500 && res.status < 600;
      if (isServerError && retries > 0) {
        await new Promise(r => setTimeout(r, backoff));
        return fetchWithRetry(url, options, retries - 1, backoff * 2);
      }
      throw new Error(`HTTP error ${res.status}`);
    }

    return await res.json();
  } catch (err) {
    const isAbort = err.name === 'AbortError';
    if (retries > 0 && !isAbort) {
      await new Promise(r => setTimeout(r, backoff));
      return fetchWithRetry(url, options, retries - 1, backoff * 2);
    }
    throw err;
  }
}

위 코드는 타임아웃 처리를 위해 AbortController를 사용한다. fetch retry react 상황에서 네트워크 오류를 자동으로 재시도할 때 유용하다.

React 컴포넌트에서 사용하기

재시도 로직을 훅으로 분리하면 재사용성이 높아진다. 다음은 useEffect와 함께 사용하는 예시다.

function useApi(endpoint) {
  const [data, setData] = React.useState(null);
  const [error, setError] = React.useState(null);
  const [loading, setLoading] = React.useState(false);

  React.useEffect(() => {
    let mounted = true;
    setLoading(true);
    fetchWithRetry(endpoint)
      .then(json => { if (mounted) setData(json); })
      .catch(err => { if (mounted) setError(err); })
      .finally(() => { if (mounted) setLoading(false); });

    return () => { mounted = false; };
  }, [endpoint]);

  return { data, error, loading };
}

Axios와 인터셉터 활용

Axios는 인터셉터를 통해 요청과 응답을 전역에서 다룰 수 있다. 인증 토큰 갱신, 공통 에러 처리, 로깅, 재시도 전략을 중앙에서 관리하기 좋다.

import axios from 'axios';

const api = axios.create({ baseURL: '/api', timeout: 10000 });

// 요청 인터셉터 예시
api.interceptors.request.use(config => {
  // 토큰 자동 주입 등
  const token = localStorage.getItem('token');
  if (token) config.headers.Authorization = `Bearer ${token}`;
  return config;
});

// 응답 인터셉터와 재시도 로직
api.interceptors.response.use(null, async error => {
  const config = error.config;
  if (!config) return Promise.reject(error);

  config.__retryCount = config.__retryCount || 0;
  const maxRetries = 2;

  const shouldRetry = !error.response || (error.response.status >= 500 && config.__retryCount < maxRetries);
  if (shouldRetry) {
    config.__retryCount += 1;
    const delay = Math.pow(2, config.__retryCount) * 200;
    await new Promise(r => setTimeout(r, delay));
    return api(config);
  }

  return Promise.reject(error);
});

export default api;

이 패턴은 axios interceptors react 사용 시 인증 처리와 서버 에러에 대한 중앙 통제에 적합하다.

UX 고려사항

  • 재시도 중에는 로딩 인디케이터로 상태를 명확히 표시한다.
  • 중요한 작업은 자동 재시도 대신 사용자 재시도 버튼 제공을 권장한다.
  • 지속 실패 시 친절한 오류 메시지와 문제 해결 방법 제시

로깅과 모니터링

재시도 정책과 에러를 수집해 분석하면 근본 원인 파악에 도움이 된다. 서버 로그, 클라이언트 에러 트래킹(예: Sentry)을 함께 사용한다.

결론

react api 에러 처리의 핵심은 에러 분류, 재시도 전략, 사용자 경험의 균형이다. fetch retry react 패턴과 axios interceptors react 활용법을 통해 재사용 가능한 구조를 만들고, 지수 백오프와 재시도 한도, 타임아웃 처리를 결합하면 안정성이 크게 향상된다. 마지막으로 로깅과 사용자 안내를 통해 문제를 빠르게 진단하고 복구하는 흐름을 구축한다.

react api 에러 처리 fetch retry react axios interceptors react react error handling api retry 전략 exponential backoff AbortController custom hook api