1. React로 시작한 나의 프론트엔드 여정
프론트엔드를 처음 배울 때부터 저는 React로 개발을 시작했습니다. HTML, CSS, JavaScript의 기초를 어느 정도 익힌 뒤 곧바로 React 컴포넌트를 만들고, 상태를 useState로 관리하며, 화면을 JSX로 선언하는 방식이 자연스러웠습니다.
당시 저에게 React는 마치 프론트엔드의 표준처럼 느껴졌고, 실제로 많은 기업이 React 기반으로 서비스를 운영하고 있었기 때문에 이 선택은 지극히 당연하게 여겨졌습니다. UI는 상태의 함수라는 개념도, props를 통해 데이터를 전달하는 구조도 별다른 거부감 없이 받아들였고, 상태 변화에 따라 UI가 즉시 반영되는 구조는 직관적이라고 느꼈습니다.
React에서는 "UI를 어떻게 바꿀까"보다 "UI가 어떤 상태여야 할까"를 먼저 고민하게 됩니다. 정의한 상태에 따라 UI가 자동으로 갱신되고, DOM을 직접 조작할 필요도 없었습니다. 저에게는 이 흐름이 곧 프론트엔드 개발의 기본 문법처럼 여겨졌습니다.
2. 데보션 프로젝트에서 처음 마주한 jQuery
그렇게 React에 익숙해진 상태에서, 처음으로 jQuery를 마주한 건 SKT Devocean 프로젝트를 진행할 때였습니다. 기존 시스템은 JSP 기반의 웹 서비스였고, 프론트엔드는 jQuery로 구성되어 있었습니다. 처음 코드를 열었을 때 마주한 건
$('#id').addClass('active')
같은 코드들이었고, 이 방식은 저에게 꽤 큰 문화 충격으로 다가왔습니다.
React에서는 상태만 바꾸면 화면이 알아서 바뀌는 구조였기에, DOM 요소를 직접 선택하고, 클래스를 수동으로 붙였다가 떼는 방식은 굉장히 낯설고 비효율적으로 느껴졌습니다. 어떤 동작을 구현하려면 무엇을 할지 뿐만 아니라 어떻게 할지까지 일일이 명령해야 하는 방식은 그동안의 선언형 사고방식과 정면으로 충돌했습니다.
특히나 복잡한 UI를 구성할 때, 한 번 조작된 DOM 상태가 정확히 어떤 흐름으로 변경되었는지 추적하기가 어려웠고, 이로 인해 예기치 못한 사이드 이펙트가 발생하기도 했습니다. 상태와 화면이 서로 긴밀하게 연결되어 있지 않다 보니, UI 전체를 하나의 함수처럼 바라보기보단 명령어 나열로 구성된 스크립트를 읽는 느낌에 가까웠습니다.
하지만 동시에, 나는 그 구조를 하나씩 뜯어보며 React가 추상화하고 있던 저수준 DOM 조작의 원리를 더 명확하게 이해할 수 있었습니다. 익숙하진 않았지만, 이것이 React 이전 세대의 프론트엔드 개발 방식이었고, 여전히 많은 레거시 시스템들이 이 위에 놓여 있다는 사실도 실감하게 되었습니다.
3. 선언형과 명령형의 충돌: 달력 컴포넌트 구현기
Devocean 프로젝트에서 제가 맡은 주요 작업 중 하나는 사용자 활동을 시각적으로 보여주는 달력 컴포넌트를 만드는 일이었습니다.
처음 기획 의도는 단순한 일정 확인용 달력을 넘어, 출석, 댓글, 좋아요 등 사용자의 활동을 날짜별로 시각화하여 참여를 유도하고 성취감을 줄 수 있는 게이미피케이션 요소를 만드는 것이었습니다.
문제는 이 모든 걸 jQuery로 구현해야 한다는 점이었습니다.
React였다면
map
으로 데이터를 순회하며 JSX를 리턴하고, 상태 변화에 따라 UI가 자동 갱신되도록 설계했을 작업이었지만, jQuery에선 전혀 달랐습니다.HTML 엘리먼트를 일일이
document.createElement
로 만들고, 클래스나 스타일을 수동으로 지정하며, 특정 DOM에 appendChild
로 붙여야 했습니다.내가 직접 UI를 "그리는" 동시에 "관리"까지 해야 하는 구조는 매우 번거롭고 실수 가능성도 높았습니다.
예를 들어, 달력 셀을 만들고 그 안에 활동 데이터를 원(circle) 형태로 SVG로 표시하려면, 각 날짜마다 위치와 개수를 계산해 직접
setAttribute
로 지정해야 했습니다.이 과정에서 “이건 내가 하던 방식이 아닌데…”라는 감각이 계속 따라붙었습니다.
React에서라면 상태만 바꾸면 됐을 일을, jQuery에선 매번 DOM을 추적하고 수동으로 업데이트해야 했습니다.

그럼에도 불구하고, 이 경험은 선언형 방식의 효율성을 몸으로 체감하게 해주는 계기가 되었습니다.
명령형 방식으로 같은 기능을 구현하려다 보니 자연스럽게 "React는 왜 이런 추상화를 제공했는가", "선언형이 어떤 문제를 해결해주는가"를 거꾸로 이해하게 된 셈입니다.
4. 명령형의 불편함, 그리고 얻은 통찰
달력 컴포넌트를 구현하면서 명령형 방식의 한계를 여러 차례 체감했습니다.
무엇보다 상태와 UI가 분리되어 있다는 점이 가장 큰 어려움이었습니다.
React에서는 상태를 바꾸면 UI가 자동으로 갱신되지만, jQuery에서는 상태 변경 후 UI를 “직접 조작”해야 합니다. 이 때문에 DOM의 현재 상태를 항상 의식하고 있어야 했고, 작은 실수 하나만으로도 화면과 실제 데이터 간의 불일치가 쉽게 발생했습니다.
특히 다양한 상태가 얽힌 UI를 처리할 때, 명령형 방식은 코드가 점점 복잡하고 절차적으로 변해갑니다.
DOM을 선택하고 → 변경 조건을 판단하고 → class를 붙이고 → 다른 class는 제거하는 일련의 과정은
결국 UI 변화 흐름을 사람이 머릿속으로 추적해야만 이해 가능한 구조를 만들게 되었습니다.
하지만 이런 불편함 속에서도 분명한 배움이 있었습니다.
React를 쓸 때는 보이지 않던 DOM의 내부 동작과 흐름이 jQuery에서는 적나라하게 드러났습니다.
그 덕분에 내가 평소 선언형으로 작성했던 코드가 실제로는 어떤 명령형 로직을 추상화하고 있는지를 더 깊이 이해할 수 있었습니다.
또한 명령형 방식이 무조건 나쁜 것이 아니라, 단순한 UI 변경이나 세밀한 제어가 필요한 순간엔 더 직관적일 수 있다는 점도 새롭게 깨달았습니다.
결국 중요한 건 선언형과 명령형 중 무엇이 "옳다"가 아니라, 어떤 문제에 어떤 방식이 더 적합한지를 판단하는 감각이라는 걸 배웠습니다.
5. 두 패러다임을 넘나들며 생긴 개발 관점의 변화
jQuery와 React, 명령형과 선언형이라는 두 패러다임을 모두 경험하면서, 제 안의 개발 관점에도 변화가 생겼습니다.
처음에는 선언형이 "더 나은 방식"이라고만 생각했지만, 명령형의 복잡한 흐름을 직접 구현해보고 나니 React의 선언형 추상화가 해결하고자 했던 문제들을 몸으로 체감하게 되었습니다.
그리고 동시에, 명령형 방식이 왜 필요한 순간이 존재하는지도 이해하게 되었습니다.
예를 들어, 포커스를 수동으로 이동하거나, 특정 애니메이션 타이밍에 맞춰 DOM을 조작해야 하는 경우처럼, 선언형만으로는 표현하기 어려운 세밀한 UI 제어도 분명 존재합니다.
React가 선언형 추상화를 제공하되,
useRef
나 imperative handle 같은 기능을 따로 제공하는 이유도 이제는 더 명확히 와 닿습니다.또한 jQuery 환경에서 직접 UI 흐름을 설계하다 보니, 화면을 상태 단위로 분리하고 컴포넌트화하는 습관이 React 밖에서도 자연스럽게 이어졌습니다.
그 경험 이후로는, React 프로젝트를 할 때도 단순히 동작하는 컴포넌트를 만드는 데서 그치지 않고,
상태와 뷰, 이벤트 흐름을 더 명확하게 분리하고 구조화하려는 태도를 갖게 되었습니다.
결국 이 경험은 저에게 선언형과 명령형 중 하나를 고르는 것이 아니라,
상황에 따라 두 방식을 유연하게 넘나들 수 있는 개발자가 되는 것이 더 중요하다는 교훈을 남겨주었습니다.

6. 처음 jQuery를 만나는 React 개발자에게
React로 개발을 시작한 분들이라면, 처음 jQuery를 접했을 때 저와 비슷한 충격을 받을 수 있습니다.
상태 기반의 선언형 UI에 익숙한 입장에서 보면, jQuery의 방식은 비효율적이고 불편하게 느껴질 수밖에 없습니다.
하지만 저는 그 낯섦 속에서 개발의 본질적인 흐름을 더 깊이 이해할 수 있는 기회를 얻었습니다.
jQuery는 우리가 지금 당연하게 사용하는 선언형 프레임워크들이 왜 등장했는지, 무엇을 해결하려고 했는지를 거꾸로 보여주는 도구였습니다.
명령형의 불편함을 직접 겪어보면, 추상화의 가치를 더 명확히 이해하게 됩니다.
또한 지금도 수많은 레거시 시스템이 jQuery로 구성되어 있다는 현실을 감안하면, 이해하고 다룰 수 있는 능력 자체가 하나의 경쟁력이 되기도 합니다.
React만으로 개발을 시작한 저에게 jQuery는 단순히 과거의 기술이 아니었습니다.
프론트엔드 패러다임의 흐름을 이해하고, 더 유연한 개발자가 되기 위한 자극제였다고 생각합니다.
처음 접했을 땐 낯설고 불편하더라도, 그 안에 담긴 맥락을 이해하려는 시도는 분명 개발자로서의 시야를 넓혀줄 것입니다.
