기술 포스트

jQuery에서 React로 — 화면을 다루는 방식이 완전히 달라집니다


Article

퍼블리셔라면 jQuery를 한 번쯤은 써봤을 겁니다. $('.tab-item').click(function() { ... }) 같은 코드가 손에 익은 분도 있을 겁니다.

React는 화면을 다루는 방식이 jQuery와 근본적으로 다릅니다. 이 차이를 먼저 이해해야 React 코드가 왜 그런 식으로 생겼는지 납득이 됩니다.

명령형 — "이걸 찾아서, 이렇게 바꿔"

jQuery 방식을 명령형(Imperative) 이라고 합니다. 화면을 바꾸고 싶을 때 어떻게 바꿀지를 하나하나 지시하는 방식입니다.

카운터를 예로 들어보겠습니다.

<p id="count">0</p>
<button id="plus-btn">+1</button>
// jQuery 방식
let count = 0;

$('#plus-btn').click(function() {
  count += 1;
  $('#count').text(count);   // 직접 찾아서, 직접 바꾼다
});

이 코드가 하는 일을 말로 풀면 이렇습니다.

  1. 버튼을 찾아라
  2. 클릭하면 count를 1 올려라
  3. #count 요소를 찾아라
  4. 그 요소의 텍스트를 직접 바꿔라

모든 단계를 개발자가 직접 명령합니다. 요소를 찾는 것도, 값을 바꾸는 것도 전부 수동입니다.

선언적 — "이 상태일 때 화면은 이렇게 보여야 해"

React 방식은 선언적(Declarative) 입니다. 화면을 어떻게 바꿀지가 아니라, 어떤 상태일 때 화면이 어떻게 보여야 하는지를 선언합니다.

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>{count}</p>
      <button onClick={() => setCount(count + 1)}>+1</button>
    </div>
  );
}

이 코드가 하는 일을 말로 풀면 이렇습니다.

  1. count라는 상태가 있다
  2. 화면에는 count 값을 보여준다
  3. 버튼을 누르면 count를 1 올린다
  4. 화면 업데이트는 React가 알아서 한다

4번이 핵심입니다. 개발자는 DOM을 직접 건드리지 않습니다. 상태만 바꾸면 화면은 자동으로 따라옵니다.

비유로 정리

명령형(jQuery) 은 택시 타고 목적지까지 가는 것과 같습니다.

"여기서 좌회전하세요. 300m 직진하세요. 사거리에서 우회전하세요. 저기 빌딩 앞에서 세워주세요."

경로의 모든 단계를 직접 지시합니다.

선언적(React) 은 내비게이션에 목적지만 입력하는 것과 같습니다.

"강남역이요."

어떻게 갈지는 내비게이션(React)이 알아서 처리합니다.

간단할 때는 차이가 없습니다

카운터 하나 만드는 정도라면 jQuery가 오히려 간단해 보입니다. 코드도 짧고 직관적입니다.

문제는 복잡해질 때 드러납니다.

복잡해지면 명령형은 스파게티가 됩니다

탭 메뉴를 jQuery로 만든다고 해봅시다. 탭 버튼을 클릭하면:

  1. 기존 활성 탭의 active 클래스를 제거하고
  2. 클릭한 탭에 active 클래스를 추가하고
  3. 기존 탭 내용을 숨기고
  4. 클릭한 탭의 내용을 보여주고

여기에 요구사항이 추가되면?

  • URL 해시에 따라 초기 탭이 달라져야 합니다.
  • 탭 전환 시 애니메이션이 필요합니다.
  • 특정 탭은 로그인해야 볼 수 있습니다.

이런 조건이 쌓이면 "어떤 요소를 찾아서 어떻게 바꿀지"를 지시하는 코드가 점점 꼬입니다. 어떤 상태에서 어떤 DOM을 건드려야 하는지 추적하기가 어려워집니다.

React라면?

function Tabs() {
  const [activeTab, setActiveTab] = useState(0);

  return (
    <div>
      {tabs.map((tab, i) => (
        <button
          key={i}
          className={i === activeTab ? "active" : ""}
          onClick={() => setActiveTab(i)}
        >
          {tab.title}
        </button>
      ))}
      <div>{tabs[activeTab].content}</div>
    </div>
  );
}

activeTab이라는 상태 하나만 관리하면 됩니다. 이 값이 바뀌면 화면이 알아서 갱신됩니다. 어떤 버튼에 active 클래스를 넣고 뺄지, 어떤 콘텐츠를 보여주고 숨길지를 직접 지시하지 않습니다.

핵심 차이 요약

명령형 (jQuery) 선언적 (React)
관심사 어떻게 바꿀 것인가 무엇을 보여줄 것인가
DOM 접근 직접 찾아서 직접 수정 React가 알아서 처리
상태 관리 변수 + DOM 동기화를 수동으로 상태 변경 → 자동 렌더링
복잡도 증가 시 스파게티 코드 위험 상태 중심으로 관리 가능

퍼블리셔에게 어떤 의미인가

jQuery에 익숙한 퍼블리셔가 React를 처음 보면 어색합니다. HTML 따로, JS 따로 분리하는 게 당연했는데, React에서는 한 파일 안에 마크업과 로직이 같이 있으니까요.

하지만 이게 바로 선언적 UI의 장점입니다. 화면이 어떤 상태에서 어떻게 보여야 하는지가 한눈에 보입니다. 마크업과 로직이 분리되어 있으면 오히려 "이 화면이 지금 어떤 상태인지" 파악하려고 여러 파일을 왔다갔다 해야 합니다.

다음 글에서는 React에서 처음 마주치는 JSX 문법에 대해 알아보겠습니다. HTML이랑 비슷하게 생겼는데 미묘하게 다른, 그 문법입니다.