WIKIReact 컴포넌트
플레이북

React 컴포넌트

화면 조각이면서 동시에 실행되는 함수다.

React컴포넌트렌더링함수프론트엔드 기초
프론트엔드프론트 입문4분

한눈에

  • 컴포넌트의 절반은 화면 조각(버튼·카드를 재사용 단위로 쪼갠 레고) — 맞지만 절반뿐
  • 진짜 정체는 실행되는 함수 — props 받아 'UI 설명서'를 반환한다 (HTML 조각이 아님)
  • 렌더링 = 그 컴포넌트 함수를 실행해서 실제 UI(HTML)를 만드는 것
  • 그럼 이 함수를 누가·어디서 실행? CSR=브라우저가 실행 / SSR=서버가 미리 실행
  • '화면 조각'을 '실행되는 함수'로 보면 SSR·CSR·Server Component가 '어디서 돌릴까' 하나로 수렴

React를 처음 배우면 컴포넌트를 이렇게 배운다. "버튼, 헤더, 카드를 재사용할 수 있게 쪼갠 화면 조각이다." 레고 블록 비유가 딱 붙는다. 맞는 말이다. 그런데 이건 컴포넌트의 절반만 본 것이다. 나머지 절반, 그리고 사실은 더 중요한 절반이 있다. 컴포넌트는 실행되는 함수다.

두 얼굴: 화면 조각, 그리고 함수

눈에 보이는 얼굴은 화면 조각이다. 헤더 하나, 카드 하나, 버튼 하나를 독립된 블록으로 떼어 재사용하고 조립한다. 이 감각이 틀린 건 아니다. 화면을 블록으로 쪼개 관리하는 게 컴포넌트의 실용적 이점이니까.

문제는 여기서 멈추면 "컴포넌트 = HTML 덩어리"라는 오해가 굳는다는 점이다. 그러면 뒤에 나오는 렌더링·SSR·Server Component 이야기가 전부 따로 노는 암기 과목이 된다. 다른 얼굴을 봐야 그게 하나로 꿰인다.

컴포넌트는 함수다

React 컴포넌트는 HTML 조각이 아니다. 함수다. 입력(props)을 받아 "화면이 이렇게 생겨야 한다"는 설명서를 반환하는 함수.

function ChatBox({ messages }) {
  return (
    <div>
      {messages.map((m) => (
        <p>{m.text}</p>
      ))}
    </div>
  )
}

이건 "채팅창 모양"이 아니다. messages라는 입력을 받아, 그걸로 <div> 안에 메시지들을 그린 UI 설명서를 반환하는 함수다. 설명서일 뿐이라, 이 함수가 실행돼야 비로소 실제 HTML이 나온다. 가만히 있는 ChatBox는 아직 아무 화면도 아니다 — 실행 버튼을 누르기 전의 함수다.

그래서 렌더링(rendering)이란 이 컴포넌트 함수를 실행해서 UI 결과물을 만드는 것이다. 화면을 "그린다"기보다, 함수를 "돌려서" 그 반환값(설명서)을 실제 화면으로 바꾸는 과정이다.

그럼 누가, 어디서 실행하나

여기서 아주 자연스러운 질문이 하나 튀어나온다. "이 함수를 대체 누가, 어디서 실행하지?" 이 질문이 핵심이다.

컴포넌트 = 함수
props를 받아 UI 설명서(JSX)를 반환한다
실행 = 렌더링
이 함수를 돌려야 실제 HTML이 나온다
CSR — 브라우저가 실행
JS를 다운받아 브라우저에서 함수를 돌려 화면을 그림
SSR — 서버가 미리 실행
서버가 먼저 함수를 돌려 완성된 HTML을 브라우저로 전달

똑같은 ChatBox 함수인데 실행하는 장소만 다르다. CSR(Client-Side Rendering)이면 브라우저가 자바스크립트를 받아 그 자리에서 함수를 돌린다. SSR(Server-Side Rendering)이면 서버가 미리 함수를 돌려 완성된 HTML을 내려준다. 같은 함수, 다른 무대. 이 "어디서 실행하느냐"가 바로 모든 렌더링 논의의 정체다.

시각을 바꾸면 전부 하나로 수렴한다

컴포넌트를 "화면 조각"으로만 보면 SSR·CSR·Server Component가 서로 상관없는 세 개의 낯선 용어로 보인다. 그런데 컴포넌트를 **"실행되는 함수"**로 바꿔 보면 셋이 전부 한 문장으로 접힌다 — "그 함수를 어디서 돌릴까."

  • SSR / CSR — 이 함수를 서버에서 미리 돌릴까, 브라우저에서 돌릴까
  • Server / Client Component — 이 함수 조각을 서버에만 둘까, 브라우저까지 보내 다시 살릴까

관점 하나만 바꿨을 뿐인데, 암기하던 세 용어가 "실행 장소를 고르는 문제" 하나로 수렴한다. 컴포넌트를 함수로 보는 순간 얻는 가장 큰 이득이 이것이다.

우리 프로젝트에선

지금 읽고 있는 이 노트를 감싼 위키 컴포넌트들 — 위의 <Flow>, 맨 위 <Cheat> 같은 것들 — 이 전부 함수다. 이 0to1 블로그는 빌드 때 HTML로 구워지는(SSG) 사이트라, 이 컴포넌트 함수들이 서버(빌드 시점의 Node)에서 실행돼 죽은 HTML로 변한 뒤 화면에 박힌다. 지금 보는 이 상자들은 "실행이 끝난 함수의 결과물"인 셈이다.

즉 나한테 컴포넌트는 "화면 조각"이기 이전에 "빌드할 때 서버가 돌리는 함수"로 먼저 와닿았다. 렌더링을 언제·어디서 하느냐는 렌더링 노트에, "그 함수를 서버에만 둘지 브라우저까지 보낼지"의 더 깊은 갈림은 Server/Client Component 노트에 이어진다.

더 읽기

컴포넌트가 함수로서 언제·어떻게 실행되는지 더 파고든 글들. 감이 안 잡힐 때 하나씩.