리액트에 대한 긍정적인 목소리가 조금씩 커뮤니티에 퍼져나가면서, 개발자들은 자신들이 오랫동안 의지해왔던 도구, jQuery에 대해 다시 생각하기 시작했다. jQuery는 지난 몇 년간 프론트엔드 개발의 제왕이었다. 어떤 새로운 프레임워크가 등장하든, 결국 DOM 조작이 필요한 순간에는 모두가 jQuery의 강력한 셀렉터와 편리한 API에 의존했다.
하지만 리액트를 경험한 개발자들은, jQuery가 더 이상 필요하지 않을지도 모른다는 생각을 하기 시작했다.
한 개발자는 리액트와 jQuery를 함께 사용하는 프로젝트의 고충을 토로하는 글을 올렸다.
“저는 리액트 컴포넌트의 componentDidMount 안에서, 특정 자식 요소에 애니메이션을 주기 위해 jQuery의 slideDown() 메서드를 사용했습니다. 처음에는 잘 작동했죠. 하지만 리액트가 리렌더링을 하면서 문제가 발생했습니다. 리액트는 jQuery가 DOM을 직접 수정한 사실을 전혀 알지 못합니다. 리액트의 버추얼 DOM과 실제 DOM의 상태가 엇갈리기 시작했고, 결국 예측 불가능한 버그들이 터져 나왔습니다.”
그의 경험은 많은 개발자들의 공감을 샀다. 리액트와 jQuery는 근본적으로 다른 철학을 가진 두 세계였다.
- jQuery: “내가 직접 DOM을 찾아가서, 명령을 내려 상태를 바꾸겠다.” (명령형)
- 리액트: “나는 DOM을 직접 만지지 않겠다. 상태가 바뀌면, 그에 맞는 DOM의 모습을 선언할 뿐이다.” (선언형)
물을 거슬러 올라가려는 jQuery와, 위에서 아래로 흐르려는 리액트. 이 둘을 한 프로젝트 안에서 섞어 쓰는 것은 언제나 충돌의 위험을 안고 있었다.
리액트 커뮤니티에서는 점차 ‘탈(脫) jQuery’ 움직임이 일어났다.
“jQuery의 셀렉터($)가 필요한가요? 리액트에서는 React.findDOMNode를 사용하거나, ref를 통해 특정 DOM 노드에 직접 접근할 수 있습니다.”
“jQuery의 이벤트 핸들러(.on())가 필요한가요? 리액트는 JSX 안에서 onClick, onChange 같은 합성 이벤트(Synthetic Events)를 제공합니다.”
“jQuery의 애니메이션(.fadeIn(), .slideUp())이 필요한가요? CSS 트랜지션을 사용하거나, 리액트 전용 애니메이션 라이브러리를 사용하는 것이 상태와 UI의 동기화를 깨뜨리지 않는 더 나은 방법입니다.”
개발자들은 깨닫고 있었다. 리액트를 사용한다는 것은 단순히 새로운 라이브러리 하나를 추가하는 것이 아니었다. 그것은 DOM을 직접 제어하던 개발 방식 자체를 포기하고, 모든 것을 리액트의 상태 관리와 렌더링 파이프라인에 위임하는 패러다임의 전환이었다.
물론, jQuery가 당장 사라지지는 않을 터였다. 간단한 웹사이트나 정적인 페이지를 만드는 데 있어서 jQuery의 간편함은 여전히 유효했다.
하지만 복잡한 상태 변화와 수많은 사용자 인터랙션을 다뤄야 하는 ‘웹 애플리케이션’의 영역에서는, 상황이 달라지고 있었다. 상태와 뷰의 동기화를 맞추는 데 지친 개발자들은, jQuery가 제공하는 편리함보다 리액트가 제공하는 예측 가능성과 안정성에 더 큰 가치를 두기 시작했다.
마치 자동차가 처음 등장했을 때, 사람들이 여전히 단거리 이동에는 말을 이용했지만 장거리 여행에는 자동차를 선택하기 시작했던 것처럼.
개발자들은 간단한 DOM 조작에는 여전히 jQuery를 썼지만, 복잡한 애플리케이션의 ‘뼈대’를 세우는 데에는 리액트를 고려하기 시작했다.
아직은 미미한 흐름이었지만, 똑똑한 개발자들은 예감하고 있었다. jQuery가 모든 것을 지배하던 영광의 시대가 서서히 저물고, 상태 중심의 선언적 UI 라이브러리들이 새로운 시대를 열어가리라는 것을. 그리고 리액트는 그 변화의 가장 선두에 서 있었다.


