페이스북 채팅창, 리액트로 다시 태어나다

632025년 10월 17일4

이론은 무르익었고, 핵심 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) 과정이 시작되었다.

  1. <ChatSearch>render 함수가 재호출된다.
  2. render 함수는 새로운 searchText('J')를 기준으로 allFriends 배열을 필터링하여, 이름이 'J'로 시작하는 친구들만 담긴 새로운 visibleFriends 배열을 계산한다.
  3. 그리고 이 visibleFriends 배열을 <FriendList> 컴포넌트의 props로 전달하며 렌더링한다.
  4. <FriendList>는 받은 props에 따라, 'John', 'Jane' 등 해당하는 <FriendListItem>들만 렌더링한다.
  5. 리액트의 Diffing 알고리즘이 이전 버추얼 DOM과 새로운 버추얼 DOM을 비교하여, 실제 DOM에서는 친구 목록의 일부 <li> 요소들만 바뀌었다는 것을 감지하고 최소한의 업데이트를 수행한다.

결과는 놀라웠다. 개발자들은 더 이상 DOM의 요소를 숨기거나 보여주고, 텍스트를 바꾸는 등의 명령형 코드를 단 한 줄도 작성하지 않았다. 그들은 오직 <ChatSearch> 컴포넌트의 state가 어떻게 변해야 하는지만을 선언했다. 그러자 UI 전체가 마치 살아있는 것처럼, 그 상태에 맞춰 완벽하게 반응했다.

몇 주 후, 리액트로 다시 태어난 채팅창 검색 기능은 페이스북의 내부 테스트 서버에 조용히 배포되었다.
겉보기에는 이전과 똑같았다. 하지만 그 내부에서는, 스파게티처럼 얽혀있던 코드 대신, 위에서 아래로 흐르는 명료한 데이터의 강물이 흐르고 있었다.

버그 리포트는 극적으로 줄었고, 새로운 기능을 추가하는 속도는 눈에 띄게 빨라졌다. 이 작은 성공은 단순한 기능 개선이 아니었다. 리액트라는 새로운 패러다임이 페이스북 규모의 실제 제품에서도 통할 수 있다는, 강력하고 실증적인 증거였다. 팀의 자신감은 하늘을 찔렀다.