컴포넌트
Component
개념
화면의 한 조각을 구조와 스타일과 동작까지 한 덩어리로 묶어 여러 화면에서 다시 쓰는 코드 단위입니다.
등장 배경
화면을 만드는 코드가 구조와 스타일과 동작으로만 나뉘던 시절이 있었습니다. 무엇이 있는지는 HTML 파일에, 어떻게 보일지는 CSS 파일에, 누르면 무슨 일이 생기는지는 자바스크립트 파일에 적혔습니다. 세로로 자른 분류라서 한 화면을 이해하려면 세 파일을 동시에 열어야 했습니다.
문제는 같은 버튼이 여러 화면에 나올 때 드러났습니다. 로그인 화면의 확인 버튼과 결제 화면의 확인 버튼과 설정 화면의 저장 버튼은 생김새가 같은데 코드는 세 군데에 따로 있었습니다. 만드는 사람은 이미 있는 버튼의 마크업을 복사해 붙였고, 스타일 이름이 겹치지 않게 뒤에 숫자를 붙였습니다.
그래서 색 하나를 바꾸는 일이 파일을 열두 개 여는 일이 됐습니다. 디자이너가 버튼 모서리를 조금 둥글게 하자고 하면 개발자는 검색으로 비슷한 코드를 찾아 하나씩 고쳤고, 한두 개는 늘 빠졌습니다. 빠진 자리는 대개 자주 안 쓰는 화면이라 몇 달 뒤 사용자가 알려 줬습니다. 버튼 하나가 이 정도니 목록이나 표처럼 손이 더 가는 조각은 아예 손대지 않고 새로 하나 더 만드는 쪽을 택했습니다. 컴포넌트는 이 분류를 가로로 다시 자른 결과입니다. 언어별로 나누는 대신 화면의 조각별로 나눕니다.
작동 방식
버튼 하나에 필요한 세 가지를 한 파일에 담고 이름을 붙여 둡니다. 버튼의 구조, 버튼의 모양, 눌렸을 때의 동작이 그 안에 함께 들어갑니다. 다른 화면에서는 그 이름을 부르기만 합니다.
쓰는 순서는 대체로 이렇습니다.
- 조각을 정의합니다. 버튼이라는 이름의 조각을 만들고, 안에 들어갈 태그와 여백과 색, 누를 때 실행할 함수를 함께 적습니다.
- 밖에서 받을 값을 정합니다. 버튼마다 글자와 색이 달라야 하니 그 부분은 고정하지 않고 사용하는 쪽에서 넘겨받습니다. 이렇게 넘기는 값을 프롭이라고 부릅니다.
- 필요한 곳에서 불러 씁니다. 결제 화면에서는 글자를 결제하기로, 설정 화면에서는 저장으로 넘기면 같은 정의에서 다른 버튼 두 개가 나옵니다.
- 조각 안에 조각을 넣습니다. 버튼과 입력칸을 모아 폼을 만들고, 폼과 제목을 모아 카드를 만듭니다. 화면 하나가 결국 제일 바깥쪽 조각 하나가 됩니다.
정의가 한 곳에 있으니 고치는 자리도 한 곳입니다. 모서리를 둥글게 하는 작업이 파일 하나를 고치는 일이 되고, 그 파일을 쓰는 모든 화면이 같이 바뀝니다. 이 성질은 방향이 양쪽입니다. 한 곳을 고치면 열두 화면이 함께 고쳐지지만, 한 곳을 잘못 고쳐도 열두 화면이 함께 망가집니다. 그래서 여러 화면이 쓰는 조각을 고칠 때는 어디에서 쓰이고 있는지부터 세어 보는 것이 순서입니다.
대신 새로운 고민이 생깁니다. 조각이 기억해야 하는 값을 어디에 둘지입니다. 이걸 다루는 일을 상태 관리라고 부릅니다. 지금 로그인한 사람이 누구인지 같은 값은 여러 조각이 함께 봐야 하는데, 위에 있는 조각이 아래로 한 단계씩 넘겨주다 보면 중간에 낀 조각들이 쓰지도 않는 값을 받아 넘기기만 합니다. 이 상황에 프롭 드릴링이라는 이름이 따로 붙어 있습니다.
쓰이는 곳
화면을 새로 만드는 일은 대개 이미 있는 조각을 찾는 데서 시작합니다. 이 화면에 필요한 버튼과 입력칸과 표가 이미 정의돼 있는지 보고, 있으면 가져다 쓰고 없으면 새로 만듭니다. 이때 만들어 둔 조각을 한곳에 모은 것이 컴포넌트 라이브러리입니다.
디자인 쪽에서도 같은 단위로 화면을 이야기합니다. 아토믹 디자인은 작은 부품부터 쌓아 화면을 구성하는 방법론인데, 디자인 도구의 부품과 코드의 조각이 같은 이름을 갖도록 맞춰 두면 디자이너가 부품 하나를 고쳤을 때 개발자가 고칠 파일이 바로 정해집니다. 이름이 어긋나 있으면 매번 어느 버튼을 말하는지부터 확인해야 합니다.
코드 리뷰에서도 자주 나옵니다. 한 조각이 400줄을 넘고 안에서 데이터를 받아오고 계산도 하고 화면도 그리면 쪼개자는 말이 나옵니다. 다만 쪼개는 것이 늘 이득은 아닙니다. 한 화면에서만 쓰는 조각을 셋으로 나누면 파일만 늘고 읽는 사람은 세 파일을 오가야 합니다.
실무 용례
"그 버튼 새로 만들지 말고 기존 컴포넌트에 색 프롭 하나 추가해서 쓰죠."
같은 것을 두 벌 만들지 말고 기존 정의를 넓히자는 제안입니다.
"이 컴포넌트가 너무 많은 걸 알고 있어요. 데이터 가져오는 부분은 밖으로 빼는 게 좋겠습니다."
조각 하나가 화면 그리기와 데이터 처리를 같이 하고 있어 나누자는 뜻입니다.
"디자인 시스템에 없는 모양이라 이번엔 일회성 컴포넌트로 갈게요."
재사용을 전제로 하지 않고 이 화면에서만 쓰겠다는 선언입니다.
페이지덱에서 민서가 버튼 높이를 40픽셀에서 44픽셀로 올리자고 제안한 적이 있습니다. 태오가 확인해 보니 버튼 정의는 한 곳이었지만 그 정의를 쓰지 않고 따로 만든 버튼이 화면 셋에 남아 있었습니다. 전부 정의를 쓰도록 바꾸는 데 이틀이 걸렸고, 그 뒤로 높이 조정은 파일 한 줄을 고치는 일이 됐습니다.
흔한 오해
컴포넌트로 나누기만 하면 재사용된다고 보는 경우가 흔합니다. 파일을 따로 뽑아 이름을 붙여 두면 다시 쓸 준비가 된 것처럼 보이니 그렇게 느낄 만합니다. 그런데 실제로 다시 쓰이려면 그 조각이 자기 화면의 사정을 모르고 있어야 합니다. 결제 화면의 항목 이름을 안에서 직접 읽는 조각은 다른 화면에서 부를 수 없고, 결국 비슷한 조각이 하나 더 생깁니다. 재사용을 가르는 것은 파일이 나뉘었는지가 아니라 필요한 값을 전부 밖에서 받는지입니다.
잘게 쪼갤수록 좋다고 읽는 것도 자주 보는 실수입니다. 조각 하나가 40줄을 넘으면 나누는 편이 깔끔해 보이지만, 한 화면에서만 쓰는 조각을 여섯으로 나누면 흐름을 따라가려고 파일 여섯 개를 열게 됩니다. 나누는 기준은 줄 수가 아니라 두 곳 이상에서 쓰이는지, 또는 안에서 하는 일이 둘로 뚜렷이 갈리는지입니다. 목록을 받아오는 일과 그 목록을 표로 그리는 일은 뚜렷이 갈리니 나눌 만하고, 표의 머리와 몸통은 늘 같이 바뀌니 붙여 두는 편이 낫습니다.
자주 헷갈리는 용어
| 용어 | 무엇을 가리키는가 | 컴포넌트와의 차이 |
|---|---|---|
| UI 컴포넌트 | 디자인 시스템에 정의된 화면 부품 | 디자인 쪽의 단위입니다. 컴포넌트는 그것을 구현한 코드이고, 둘은 대개 짝이지만 코드에만 있는 조각도 많습니다 |
같이 보면 좋은 페이지
연관 용어
마지막 업데이트 2026-09-16