JavaScript에서 fetch로 API 데이터를 가져온 뒤 바로 data.map(...)을 호출했는데 화면이 비는 경우가 많습니다. 코드는 짧아 보이지만 실제 원인은 대부분 Promise를 배열처럼 사용했거나, 응답을 JSON으로 바꾸기 전에 렌더링하려고 했기 때문입니다.

자주 나오는 실패 코드

const users = fetch("/api/users");

users.map(user => {
  return `<li>${user.name}</li>`;
});

이 코드는 users가 배열이라고 가정합니다. 하지만 fetch()가 돌려주는 값은 배열이 아니라 Promise입니다. Promise는 아직 끝나지 않은 작업을 나타내기 때문에 map을 바로 호출할 수 없습니다.

왜 화면이 비어 보이나요?

  • fetch()는 네트워크 요청을 시작하고 Promise를 반환합니다.
  • 응답 본문은 response.json()으로 한 번 더 파싱해야 합니다.
  • 데이터가 도착하기 전에 렌더링하면 배열이 없어서 빈 화면이나 오류가 납니다.
  • 실무에서는 로딩, 실패, 빈 데이터, 성공 상태를 나눠야 원인을 빨리 찾을 수 있습니다.

수정 코드: await로 순서를 명확히 나누기

async function loadUsers() {
  const response = await fetch("/api/users");

  if (!response.ok) {
    throw new Error("사용자 목록을 불러오지 못했습니다.");
  }

  const users = await response.json();

  return users.map(user => {
    return `<li>${user.name}</li>`;
  }).join("");
}

핵심은 세 단계입니다. 첫째, fetch 요청이 끝날 때까지 기다립니다. 둘째, 응답을 JSON 데이터로 변환합니다. 셋째, 그 데이터가 배열인지 확인한 뒤 화면에 렌더링합니다.

실무 체크리스트

  • fetch() 결과를 변수에 담았을 때 그 값이 Promise인지 확인합니다.
  • await response.json()을 빠뜨리지 않았는지 봅니다.
  • API 실패 시 response.ok를 확인합니다.
  • 데이터가 배열이 아닐 가능성이 있으면 Array.isArray(data)로 방어합니다.
  • 화면에는 로딩, 에러, 빈 결과, 성공 결과를 각각 표시합니다.

직접 풀어볼 문제

아래 실습에서는 fetch 흐름을 함수로 분리하고, Promise와 실제 배열 데이터를 구분하는 연습을 할 수 있습니다.

JavaScript fetch/async 실습 문제 풀기

해설팩으로 이어서 보기

숫자 문자열 계산, 배열 원본 변경, fetch/async 흐름, DOM 이벤트 중복 등록처럼 실무 화면에서 자주 깨지는 JavaScript 실수를 실패 코드와 수정 코드로 정리했습니다.

JavaScript 실무 실수 해설팩 샘플 보기

이메일로 샘플을 받고 싶다면 아래 신청 페이지에서 JavaScript 해설팩을 선택하면 됩니다.

프론트엔드 실무 해설팩 신청하기


프론트엔드 실무 코딩 랩에서 더 알아보기

구독을 신청하면 최신 게시물을 이메일로 받아볼 수 있습니다.

댓글 남기기

  • React useEffect cleanup이 없어서 이벤트 리스너가 두 번 실행될 때

    React에서 버튼을 한 번 눌렀는데 로그가 두 번 찍히거나, 스크롤 이벤트가 예상보다 많이 실행되거나, resize 처리 함수가 여러 번 호출되는 경우가 있습니다. 이때 원인은 보통 두 가지입니다. 개발 환경의 StrictMode 때문에 effect가 한 번 더 점검되는 경우 useEffect 안에서 등록한 이벤트 리스너를 cleanup 하지 않은 경우 이번 글은 두 번째 경우, 즉 addEventListener를 등록하고 제거하지…

  • React key에 index를 쓰면 입력값이 다른 항목으로 이동하는 이유

    React key에 index를 쓰면 입력값이 다른 항목으로 이동하는 이유 증상: 삭제했는데 다른 행의 입력값이 바뀝니다 React에서 목록을 렌더링할 때 key={index}를 쓰면 처음에는 문제가 없어 보입니다. 하지만 항목을 삭제하거나 정렬하거나 필터링하는 순간, 화면 상태가 예상과 다르게 남는 경우가 생깁니다. 실무에서는 이런 식으로 보입니다. 두 번째 항목을 삭제했는데 세 번째 항목의 입력값이 두 번째 자리로 따라옵니다. 체크박스를…

  • JavaScript filter return 빼먹으면 빈 배열이 되는 이유

    JavaScript filter 결과가 빈 배열이라면 콜백의 return을 확인하세요. 중괄호와 암시적 반환, truthy/falsy 판정, 수정 코드와 디버깅 방법을 예제로 설명합니다.

  • JavaScript 함수가 undefined를 반환하는 이유

    JavaScript 함수가 undefined를 반환하는 이유: console.log만 쓰고 return을 빼먹었을 때 계산 함수는 화면에 값을 찍는 코드가 아니라, 호출한 쪽이 다시 쓸 값을 돌려주는 코드입니다. 그런데 처음 JavaScript를 배울 때 console.log로 값이 보이면 함수가 값을 반환한다고 착각하기 쉽습니다. 검색해서 들어온 경우 먼저 확인할 증상 console.log에는 값이 찍히는데 변수에는 undefined가 들어갑니다. 계산 함수, 검증 함수, API 가공…

  • React input 값이 안 바뀌는 이유: value만 넣고 onChange를 빠뜨렸을 때

    React에서 <input value={email} />처럼 값을 넣었는데 입력창이 수정되지 않는 경우가 있습니다. 화면에는 input이 보이지만 타이핑해도 값이 그대로라서 처음 보면 브라우저나 CSS 문제처럼 느껴집니다. 실제 원인은 대부분 value는 상태를 보여주는데, onChange로 상태를 바꾸는 연결이 빠졌기 때문입니다. 자주 나오는 실패 코드 이 코드는 email 상태를 input에 연결했습니다. 하지만 사용자가 타이핑했을 때 setEmail을 호출하는 코드가 없습니다. 그래서 input은…

← 뒤로

응답해 주셔서 감사합니다. ✨

프론트엔드 실무 코딩 랩에서 더 알아보기

지금 구독하여 계속 읽고 전체 아카이브에 액세스하세요.

계속 읽기

프론트엔드 실무 코딩 랩에서 더 알아보기

지금 구독하여 계속 읽고 전체 아카이브에 액세스하세요.

계속 읽기