이론은 무르익었고, 핵심 API는 자리를 잡았다. 이제 리액트의 가치를 실제 제품으로 증명해야 할 때가 왔다. 톰은 팀의 다음 목표를 명확히 했다.
“뉴스피드의 댓글 입력창에 이어, 페이스북 채팅창의 검색 기능을 리액트로 재구축한다. 이것이 우리의 첫 번째 공식적인 실전 투입이다.”
페이스북 채팅창의 친구 검색 기능은 겉보기엔 단순했지만, 내부적으로는 악명 높은 스파게티 코드의 온상이었다. 사용자가 검색창에 친구 이름을 입력하기 시작하면, 수많은 일들이 동시에 벌어져야 했다.
- 입력된 텍스트를 기반으로 실시간으로 친구 목록을 필터링해야 했다.
- 일치하는 친구가 없으면 ‘결과 없음’ 메시지를 보여줘야 했다.
- 검색 결과 목록은 스크롤이 가능해야 했다.
- 각 친구 항목에 마우스를 올리면 배경색이 바뀌어야 했다.
기존 코드는 이 모든 로직이 jQuery 이벤트 핸들러 안에 뒤섞여, DOM의 상태와 자바스크립트 변수의 상태가 수시로 엇갈리는 문제를 안고 있었다.
리액트 팀은 이 혼돈을 질서로 바꾸는 작업에 착수했다. 그들은 먼저 UI를 컴포넌트 단위로 분해했다.
<ChatSearch>: 전체 검색 기능을 감싸는 최상위 컨테이너 컴포넌트.<SearchInput>: 사용자가 텍스트를 입력하는 검색창 컴포넌트.<FriendList>: 필터링된 친구 목록을 보여주는 컴포넌트.<FriendListItem>: 목록 안의 개별 친구 항목을 나타내는 컴포넌트.
가장 중요한 역할은 최상위 컴포넌트인 <ChatSearch>가 맡았다. 이 컴포넌트는 모든 상태(state)를 책임지는 유일한 ‘관리자’였다.
// ChatSearch 컴포넌트의 state 구조 (개념)
getInitialState: function() {
return {
// 사용자가 입력한 검색어
searchText: '',
// 서버에서 받아온 전체 친구 목록 (props로 받을 수도 있음)
allFriends: [ ... ],
// 검색어에 따라 필터링된, 화면에 보여질 친구 목록
visibleFriends: [ ... ]
};
},
모든 마법은 searchText 상태가 변할 때 일어났다.
사용자가 검색창(SearchInput)에 키보드를 입력하면, SearchInput은 DOM을 직접 바꾸지 않았다. 그저 onChange 이벤트를 통해 부모인 <ChatSearch>에게 “사용자가 ‘J’를 입력했습니다”라고 알릴 뿐이었다.
그러면 <ChatSearch>의 이벤트 핸들러가 setState를 호출하여 searchText를 갱신했다.
this.setState({ searchText: 'J' });
setState가 호출되는 순간, 리액트의 재조정(Reconciliation) 과정이 시작되었다.
<ChatSearch>의render함수가 재호출된다.render함수는 새로운searchText('J')를 기준으로allFriends배열을 필터링하여, 이름이 'J'로 시작하는 친구들만 담긴 새로운visibleFriends배열을 계산한다.- 그리고 이
visibleFriends배열을<FriendList>컴포넌트의props로 전달하며 렌더링한다. <FriendList>는 받은props에 따라, 'John', 'Jane' 등 해당하는<FriendListItem>들만 렌더링한다.- 리액트의 Diffing 알고리즘이 이전 버추얼 DOM과 새로운 버추얼 DOM을 비교하여, 실제 DOM에서는 친구 목록의 일부
<li>요소들만 바뀌었다는 것을 감지하고 최소한의 업데이트를 수행한다.
결과는 놀라웠다. 개발자들은 더 이상 DOM의 요소를 숨기거나 보여주고, 텍스트를 바꾸는 등의 명령형 코드를 단 한 줄도 작성하지 않았다. 그들은 오직 <ChatSearch> 컴포넌트의 state가 어떻게 변해야 하는지만을 선언했다. 그러자 UI 전체가 마치 살아있는 것처럼, 그 상태에 맞춰 완벽하게 반응했다.
몇 주 후, 리액트로 다시 태어난 채팅창 검색 기능은 페이스북의 내부 테스트 서버에 조용히 배포되었다.
겉보기에는 이전과 똑같았다. 하지만 그 내부에서는, 스파게티처럼 얽혀있던 코드 대신, 위에서 아래로 흐르는 명료한 데이터의 강물이 흐르고 있었다.
버그 리포트는 극적으로 줄었고, 새로운 기능을 추가하는 속도는 눈에 띄게 빨라졌다. 이 작은 성공은 단순한 기능 개선이 아니었다. 리액트라는 새로운 패러다임이 페이스북 규모의 실제 제품에서도 통할 수 있다는, 강력하고 실증적인 증거였다. 팀의 자신감은 하늘을 찔렀다.


