데이터 → 화면 — JSON을 카드로 렌더링

Day 9의 더미 카드가, 이번엔 브라우저 안에서 실시간으로 채워집니다

10초 핵심 요약

01

이건 Day 10의 .map()과 다릅니다

Day 10에서 배운 posts.map(...)은 Astro의 frontmatter 안에서 빌드 타임에 딱 한 번 실행되고, 그 결과가 이미 완성된 HTML로 구워집니다(Day 1, Day 12). 오늘 다루는 .map()은 똑같은 이름의 배열 메서드지만, 순수 JS 코드로 브라우저 안에서 실행됩니다 — 로그인/결제처럼 /functions/api/*에서 실시간으로 받아온 데이터를, 페이지가 이미 열린 뒤에 화면에 끼워 넣을 때 씁니다.

Day 10의 .map()오늘의 .map()
실행 시점빌드 타임(배포 전, 딱 1번)방문자의 브라우저 안(매번)
데이터 출처frontmatter의 더미 배열fetch로 받아온 실시간 응답
결과물이미 완성된 정적 HTMLinnerHTML로 즉석에서 삽입
02

map → join → innerHTML 패턴

function renderPosts(posts) {
  const html = posts.map(post => `
    <div class="post-card">
      <h3>${post.title}</h3>
    </div>
  `).join('');
  container.innerHTML = html;
}

posts.map(post => ...)은 배열 각 항목을 HTML 문자열로 바꾸는 작업입니다. 그 결과는 문자열 여러 개가 든 배열이라서, .join('')으로 이어붙여야 하나의 긴 문자열이 됩니다. 그걸 innerHTML에 넣으면 브라우저가 진짜 태그로 해석해 화면에 그립니다.

03

로딩 3상태를 빠짐없이 처리하기

로딩중

스피너나 "불러오는 중..." 문구 표시

성공

renderPosts로 카드 출력. 빈 배열이면 대체 메시지

실패

"데이터를 불러오지 못했습니다" 등 오류 메시지 표시

스피너는 CSS로 만들고, 데이터가 도착하면 JS로 display: none 처리해 숨기면 됩니다. 성공/실패 여부에 따라 스피너 대신 카드 또는 오류 메시지를 그 자리에 넣습니다.
04

Day 16 카드 CSS, 그대로 재사용

빌드 타임에 만든 카드든 오늘처럼 브라우저에서 즉석으로 만든 카드든 클래스 이름만 같으면(.post-card) 똑같은 CSS가 적용됩니다. 디자인을 새로 만들 필요가 없습니다. 이것이 Day 9~16에서 BEM 네이밍을 미리 정리해둔 이유입니다.

보안 주의innerHTML에 사용자가 직접 입력한 값을 그대로 넣으면 XSS(악성 스크립트 삽입) 위험이 있습니다. 신뢰할 수 있는 API 데이터에만 이 패턴을 사용하세요.
05

Day 30 완료 체크리스트

Day 10의 .map()과 오늘의 .map()이 실행 시점부터 다르다는 걸 설명할 수 있다.
더미 JSON으로 renderPosts 함수를 완성했다.
빈 배열을 넣었을 때 대체 메시지가 뜨는지 확인했다.
스스로 설명해보기 — Day 10의 .map()과 오늘의 .map()이 실행 시점부터 왜 다른지 설명할 수 있나요?

오늘의 용어

.map()
배열의 각 항목을 원하는 형태로 변환한 새 배열을 만드는 함수
.join('')
배열 안의 문자열들을 하나로 이어붙이는 함수
XSS
신뢰할 수 없는 입력을 그대로 삽입해 악성 스크립트가 실행되는 보안 취약점