본문으로 건너뛰기
프론트엔드 기초집LESSON 13

로딩·성공·에러 상태 처리

난이도초급
예상 시간35분
선수지식이전 강의

13강. 로딩·성공·에러 상태 처리

1. 이번 강의에서 해결할 문제

요청이 느리거나 실패해도 현재 화면은 게임 0개만 보여 줍니다. 사용자는 로딩 중인지, 결과가 비었는지, 오류인지 구분할 수 있어야 합니다.

2. 학습 목표

  • 요청 상태를 명시적인 값으로 모델링한다.
  • 로딩·성공·빈 결과·오류 UI를 분리한다.
  • 재시도 가능한 요청 흐름을 만든다.

3. 핵심 개념

비동기 UI에는 최소 loading, success, error 상태가 있습니다. success 안에서도 데이터가 빈 경우를 따로 안내합니다. 여러 boolean을 조합하면 불가능한 상태가 생길 수 있어 하나의 status 값이 이해하기 쉽습니다.

오류는 개발자용 세부 정보와 사용자용 안내를 구분하고, 가능하면 재시도 동작을 제공합니다.

4. 단계별 코드 예시

파일 경로: game-release-dashboard/src/App.tsx

import { useEffect, useState } from 'react';

type Status = 'loading' | 'success' | 'error';
type Game = { id: string; title: string };

function App() {
const [games, setGames] = useState<Game[]>([]);
const [status, setStatus] = useState<Status>('loading');
const [retryCount, setRetryCount] = useState(0);

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

async function loadGames() {
setStatus('loading');
try {
const response = await fetch(
import.meta.env.BASE_URL + 'data/games.json',
{ signal: controller.signal },
);
if (!response.ok) throw new Error('HTTP ' + response.status);
setGames(await response.json());
setStatus('success');
} catch (error) {
if (error instanceof DOMException && error.name === 'AbortError') return;
console.error(error);
setStatus('error');
}
}

void loadGames();
return () => controller.abort();
}, [retryCount]);

if (status === 'loading') return <p role="status">게임을 불러오는 중…</p>;
if (status === 'error') {
return <button onClick={() => setRetryCount((n) => n + 1)}>다시 시도</button>;
}
if (games.length === 0) return <p>등록된 게임이 없습니다.</p>;

return <p>{games.length}개의 게임을 불러왔습니다.</p>;
}

export default App;

5. 코드가 동작하는 이유

retryCount가 바뀌면 Effect가 새 요청을 시작합니다. try/catch가 네트워크와 HTTP 검사 오류를 error 상태로 바꾸되, 정상적인 요청 취소는 사용자 오류로 표시하지 않습니다. 조기 반환은 한 시점에 하나의 명확한 화면만 보여 줍니다.

6. 자주 하는 실수와 해결법

  • finally에서 무조건 success 처리: 성공은 JSON 저장 뒤에만 설정합니다.
  • AbortError도 실패로 표시: 취소 오류를 구분합니다.
  • 오류를 콘솔에만 남김: 사용자 안내와 재시도 버튼을 제공합니다.
  • 로딩 중 이전 오류를 유지: 새 요청 시작 시 상태를 loading으로 초기화합니다.

7. 직접 실습

성공 화면에서 게임 목록을 렌더링하고, 빈 JSON 배열을 넣었을 때 빈 상태가 나오는지 확인하세요. 로딩과 오류 문구에 role="status" 또는 적절한 live region을 적용하세요.

8. 이해 점검 질문 3개

  1. loading boolean과 error boolean만 쓰면 어떤 모순 상태가 생길 수 있나요?
  2. 빈 결과와 요청 오류를 구분해야 하는 이유는 무엇인가요?
  3. 재시도 버튼은 어떤 state 변화를 이용해 Effect를 다시 실행하나요?

9. 핵심 요약

비동기 요청은 상태 기계처럼 명시적으로 모델링합니다. 로딩, 성공, 빈 결과, 오류, 재시도를 모두 표현해야 신뢰할 수 있는 UI가 됩니다.

MINI QUIZ

로딩·성공·에러 상태 처리 미니 퀴즈

선택 즉시 정답과 해설을 확인할 수 있습니다. 결과는 이 브라우저에만 저장됩니다.

0 / 2
  1. 문제 1“로딩·성공·에러 상태 처리”의 위험한 선택을 피하려면 어떤 원칙을 적용해야 하나요?
  2. 문제 2‘오류를 콘솔에만 남김’ 실수를 판단할 때 “로딩·성공·에러 상태 처리” 강의가 제시한 기준은 무엇인가요?
LESSON STATUS

학습을 마쳤나요?

직접 실습과 점검 질문까지 확인한 뒤 완료로 표시하세요.

13강. 로딩·성공·에러 상태 처리 미완료 상태