“모든 프로필 사진을, 현재의 사각형에서 원형으로 바꿔주세요.”
기획팀의 새로운 요구사항은 간단명료했다. 하지만 그 말을 들은 맷의 얼굴은 어두워졌다. 그는 옆에 있던 톰에게 하소연했다.
“이 ‘간단한’ 작업을 하려면, 제가 몇 군데를 수정해야 하는지 아세요?”
그는 손가락을 꼽기 시작했다.
“일단 페이지 상단 헤더의 PHP 템플릿. 뉴스피드 게시물을 그리는 XHP 컴포넌트. 채팅창 친구 목록을 동적으로 생성하는 jQuery 코드. 친구 페이지의 백본 뷰… 최소 대여섯 군데는 족히 될 겁니다. 최악인 건, 그 HTML 구조가 전부 미세하게 다르다는 거예요.”
어떤 곳에서는 <img> 태그만 덩그러니 있었고, 다른 곳에서는 <a> 태그 안에 감싸여 있었다. 또 다른 곳에서는 <div>로 한번 더 포장되어 있었다. 클래스 이름도 제각각이었다. 이 모든 곳을 찾아다니며 일관성을 유지한 채 스타일을 수정하는 것은 실수하기 딱 좋은, 지루하고 위험한 작업이었다.
그들의 대화를 듣고 있던 조던 워크가 조용히 다가왔다.
“맷, 그게 바로 우리가 지금의 방식을 버려야 하는 이유입니다.”
그는 화이트보드에 <Avatar>라고 적었다.
“우리가 만들어야 할 것은 여러 개의 프로필 사진이 아닙니다. 우리는 오직 단 하나의, 완벽하게 독립된 <Avatar> 부품을 만들어야 합니다.”
조던은 자신의 비전을 설명했다.
“이 <Avatar> 부품은 자신의 render 메서드 안에, 프로필 사진을 표시하기 위한 정확한 HTML 구조와 ‘원형으로 만드는’ CSS 클래스를 모두 가지고 있습니다. 이 부품이 필요로 하는 데이터는 오직 하나, imageUrl 뿐이죠.”
그는 <Avatar> 컴포넌트를 사용하는 가상의 코드를 그렸다.
<Avatar>컴포넌트 정의 (단 하나의 파일에 존재)
// AvatarComponent.js
// ... 컴포넌트 정의 ...
render: function() {
// 이 컴포넌트는 항상 'avatar'와 'circular-shape' 클래스를 가진다.
return createDescription('img', {
className: 'avatar circular-shape',
src: this.props.imageUrl
});
}
// ...
- 애플리케이션 곳곳에서의 사용
// Header.js
// ...
var avatar = Avatar({ imageUrl: currentUser.avatarUrl });
// ...
// Post.js
// ...
var avatar = Avatar({ imageUrl: post.author.avatarUrl });
// ...
“이제, 프로필 사진의 모양을 다시 사각형으로 바꾸고 싶다면 어떻게 해야 할까요?” 조던이 물었다.
맷은 잠시 생각하더니, 놀라움에 찬 표정으로 대답했다.
“...AvatarComponent.js 파일 하나만 열어서, circular-shape 클래스를 지우면… 되겠네요.”
“정확합니다.” 조던이 말했다. “파일 하나만 수정하면, 헤더, 뉴스피드, 채팅창에 있는 수백 개의 모든 아바타가 단 한 번에, 일관되게 바뀝니다. 우리는 더 이상 흩어져 있는 수십 개의 <img> 태그를 관리할 필요가 없습니다. 오직 <Avatar>라는 부품 하나만 관리하면 되는 거죠.”
그 순간, 회의실에 있던 모든 엔지니어의 머릿속에서 혁명과도 같은 깨달음이 일어났다.
그들은 지금껏 UI를 하나의 거대한 진흙 덩어리로 보고, 필요할 때마다 여기저기를 주물러 모양을 바꿔왔다. 하지만 리액트는 UI를 표준화된 ‘레고 블록’의 집합으로 보았다.
완벽하게 디자인된 ‘아바타 블록’, ‘버튼 블록’, ‘입력창 블록’을 미리 만들어두고, 필요할 때마다 그 블록들을 가져다 조립만 하면 되는 것이다.
이 재사용성이라는 개념은 단순히 코드를 줄이는 차원이 아니었다. 개발의 복잡성을 근본적으로 낮추고, 유지보수 비용을 획기적으로 줄이며, 디자인의 일관성을 시스템적으로 보장하는, 그야말로 ‘게임 체인저’였다. 팀은 이제 자신들이 만들고 있는 것이 단순한 라이브러리가 아니라, UI 부품을 생산하는 거대한 공장의 설계도임을 확신하게 되었다.


