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 해설팩을 선택하면 됩니다.
댓글 남기기