Dev Thinking
32완료

자예측 가능한 컴포넌트 - 순수함수 원칙 적용하기

2025-08-08
12분 읽기

리액트 공식문서 기반의 리액트 입문기

들어가며

개발을 하다 보면 시간이 지남에 따라 코드가 예상치 않게 동작하거나, 특정 부분을 수정했을 때 전혀 관련 없어 보이는 다른 부분에서 문제가 발생하는 경험을 하곤 합니다. 특히 UI 개발에서는 사용자 인터랙션과 데이터 변화에 따라 화면이 복잡하게 변하기 때문에, 이러한 예측 불가능성은 개발자를 힘들게 만들고 디버깅 시간을 늘리는 주범이 됩니다.

자바스크립트로만 개발해오던 우리에게 리액트가 제시하는 '순수 컴포넌트'라는 개념은 이러한 예측 불가능성을 줄이고, 더 안정적이며 유지보수하기 쉬운 애플리케이션을 만드는 데 핵심적인 역할을 합니다. 함수형 프로그래밍의 중요한 원칙 중 하나인 '순수 함수' 개념을 UI 컴포넌트에 적용함으로써, 리액트는 항상 동일한 입력에 대해 동일한 출력을 보장하고 외부 상태를 변경하지 않는 컴포넌트를 지향합니다. (1-1편에서 다루었던 명령형 vs 선언형 개념을 다시 한번 떠올려보면 좋습니다.)

이번 편에서는 자바스크립트에서 순수 함수가 왜 중요한지, 그리고 리액트 컴포넌트가 어떻게 이 순수 함수 원칙을 따르는지 탐구해 볼 것입니다. 또한, 사이드 이펙트(Side Effect)가 무엇이며, 리액트에서 이를 어떻게 관리하는지 살펴보면서 예측 가능한 UI를 만드는 방법을 함께 고민해보고자 합니다.

예측 가능한 UI를 위한 핵심, 순수 컴포넌트 원칙

리액트가 예측 가능한 UI를 만들도록 돕는 핵심 원칙 중 하나는 바로 '순수 함수' 개념을 컴포넌트에 적용하는 것입니다. 순수 함수는 수학에서의 함수와 유사하게, 두 가지 중요한 조건을 만족하는 함수를 의미합니다.

  1. 동일한 입력, 동일한 출력: 함수에 동일한 인자를 넣으면 항상 동일한 결과값을 반환해야 합니다. 외부 상태나 시간에 따라 결과가 달라져서는 안 됩니다.
  2. 사이드 이펙트 없음: 함수는 자신의 범위를 벗어나 외부의 어떤 것도 변경해서는 안 됩니다. 전역 변수를 수정하거나, 네트워크 요청을 보내거나, DOM을 직접 조작하는 등의 행위는 사이드 이펙트로 간주됩니다.

리액트 컴포넌트는 이러한 순수 함수 원칙을 따르도록 설계되었습니다. 즉, 컴포넌트 함수는 propsstate를 입력으로 받아 항상 동일한 JSX를 반환해야 하며, 렌더링 과정에서 외부의 데이터를 직접 변경해서는 안 됩니다. 이렇게 컴포넌트가 순수하게 유지될 때, 우리는 특정 컴포넌트의 렌더링 결과가 항상 예상한 대로 나올 것이라고 확신할 수 있으며, 이는 애플리케이션의 복잡성을 크게 줄여줍니다.

그렇다면 사이드 이펙트는 정확히 무엇이며, 왜 리액트는 순수 컴포넌트를 강조하면서 사이드 이펙트를 렌더링 과정에서 피하라고 할까요? 사이드 이펙트는 함수가 자신의 주된 목적(값 반환) 외에 '부수적으로' 시스템의 상태를 변경하는 모든 작업을 말합니다. 예를 들어, console.log로 로그를 남기는 것, 데이터를 서버에 전송하는 것, 타이머를 설정하는 것, 그리고 DOM을 직접 조작하는 것 등이 모두 사이드 이펙트에 해당합니다.

리액트는 컴포넌트 렌더링 과정에서 이러한 사이드 이펙트가 발생하면 예측 불가능한 동작을 초래할 수 있다고 경고합니다. 렌더링은 언제든지, 어떤 순서로든 발생할 수 있기 때문에, 렌더링 중에 외부 상태를 변경하면 예상치 못한 버그를 유발할 수 있습니다. 예를 들어, 두 컴포넌트가 동시에 렌더링되면서 같은 전역 변수를 수정하려 한다면 경쟁 상태(Race Condition)가 발생할 수 있습니다. 리액트는 이러한 사이드 이펙트를 useEffect와 같은 특별한 '탈출구(Escape Hatch)'를 통해 컴포넌트의 생명주기(Lifecycle)에 맞춰 별도로 관리하도록 권장합니다. 이 내용은 5-3편편에서 자세히 다룰 예정이므로, 지금은 '사이드 이펙트를 분리하여 관리하는 메커니즘이 있다'는 정도만 기억하셔도 좋습니다.

자, 그럼 먼저 순수하지 못한 함수, 즉 사이드 이펙트가 있는 함수가 자바스크립트에서 어떻게 동작하는지 살펴보면서, 우리가 왜 순수 함수를 지향해야 하는지 살펴보겠습니다.

자바스크립트 (사이드 이펙트 포함): 예측 불가능한 UI 만들기

먼저 우리가 흔히 접할 수 있는 자바스크립트 방식으로, 외부 상태를 변경하고 로그를 남기는 함수를 만들어 보겠습니다. 이 예제에서는 전역 변수인 totalCount를 함수 내부에서 직접 수정하고, console.log를 통해 로그를 남기는 전형적인 사이드 이펙트가 있는 함수를 보여줍니다. 이러한 방식은 초기에는 간단해 보이지만, 애플리케이션의 규모가 커질수록 데이터 흐름을 추적하기 어렵게 만들고, 예상치 못한 버그를 유발하는 주된 원인이 됩니다.

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>JavaScript Side Effect Example</title>
  </head>
  <body>
    <h1>JavaScript Side Effect Example</h1>
    <p>현재 합계: <span id="currentTotal">0</span></p>
    <button id="incrementButton">값 5 증가</button>
 
    <script>
      // 전역 변수로 외부 상태를 관리합니다. (사이드 이펙트의 대상)
      let totalCount = 0;
 
      // 이 함수는 외부(전역 변수)의 상태를 변경하고, 콘솔에 로그를 남기는 사이드 이펙트가 있습니다.
      function incrementTotalWithSideEffect(value) {
        totalCount += value; // 외부 상태(totalCount) 변경: 함수의 순수성을 해치는 가장 큰 원인 중 하나입니다.
        console.log(`[JS] totalCount가 ${value}만큼 증가했습니다. 현재 합계: ${totalCount}`); // 콘솔 로그: 외부 시스템과의 상호작용입니다.
        document.getElementById("currentTotal").textContent = totalCount; // DOM 직접 조작: 또 다른 외부 상태(UI) 변경입니다.
        return totalCount;
      }
 
      document.getElementById("incrementButton").addEventListener("click", () => {
        incrementTotalWithSideEffect(5);
      });
 
      // 초기 렌더링
      document.getElementById("currentTotal").textContent = totalCount;
    </script>
  </body>
</html>

이 코드는 버튼을 클릭할 때마다 incrementTotalWithSideEffect 함수가 호출되어 전역 변수 totalCount의 값을 5씩 증가시킵니다. 동시에 콘솔에는 현재 합계가 출력되고, 화면의 <span> 요소도 업데이트됩니다. 여기서 totalCount += value;, console.log(...), document.getElementById(...).textContent = ... 부분이 모두 함수 외부의 상태를 변경하거나 외부 시스템과 상호작용하는 사이드 이펙트입니다. 이러한 방식은 코드를 이해하기 쉽게 만들지만, 애플리케이션의 규모가 커지면 예측 불가능한 동작을 유발할 가능성이 높아집니다. 특히, 여러 함수가 동일한 전역 변수를 수정하거나 DOM을 조작할 경우, 어떤 함수가 언제 어떻게 값을 변경했는지 추적하기 어려워 복잡성이 기하급수적으로 증가합니다.

자바스크립트 (사이드 이펙트 포함) 방식의 특징

  1. 명령형(Imperative) DOM 조작: document.getElementById와 같은 명령형 API를 사용해 HTML 요소를 직접 선택하고 변경합니다. 개발자가 UI 변경의 '방법(How)'을 상세하게 지시해야 합니다.
  2. 사이드 이펙트 남용: 함수가 전역 변수를 수정하거나, console.log로 외부 시스템과 상호작용하는 등 함수 외부의 상태를 변경하는 '사이드 이펙트'를 자유롭게 발생시킵니다.
  3. 예측의 어려움: 외부 상태에 직접 접근하고 변경하기 때문에, 함수의 호출 시점이나 순서에 따라 결과가 달라질 수 있어 예측하기 어려운 경우가 많습니다.
  4. 수동적인 동기화 책임: 데이터 변경 시 개발자가 직접 UI를 업데이트하는 코드를 작성해야 합니다. 데이터와 UI 간의 동기화가 자동으로 이루어지지 않습니다.

자바스크립트 (순수 함수 지향): 계산과 DOM 업데이트 분리하기

이번에는 자바스크립트 환경에서도 순수 함수 원칙을 지향하여 코드를 작성해 보겠습니다. 핵심은 '계산'과 'DOM 조작'이라는 두 가지 역할을 명확히 분리하는 것입니다. calculateNewTotal 함수는 오직 새로운 합계 값을 계산하여 반환하는 순수한 역할만 수행하며, 외부 상태를 직접 변경하거나 DOM을 조작하지 않습니다. 실제 DOM 업데이트는 updateDisplay 함수가 담당하며, 이 함수는 calculateNewTotal의 결과값을 받아 UI를 업데이트합니다. 이렇게 역할을 분리함으로써, calculateNewTotal 함수는 어떤 상황에서 호출되더라도 항상 동일한 입력에 대해 동일한 결과를 보장할 수 있게 됩니다.

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>JavaScript Pure Function Example</title>
  </head>
  <body>
    <h1>JavaScript Pure Function Example</h1>
    <p>현재 합계: <span id="currentTotalPure">0</span></p>
    <button id="incrementButtonPure">값 5 증가</button>
 
    <script>
      let totalCountPure = 0; // 여전히 외부 상태이지만, 직접 변경되지 않습니다.
 
      // 이 함수는 순수합니다. 주어진 입력(current, value)에만 의존하며, 외부 상태를 변경하지 않습니다.
      function calculateNewTotal(current, value) {
        // console.log(`[JS Pure] 새로운 합계 계산 중: ${current} + ${value}`); // 로그는 사이드 이펙트이므로 주석 처리
        return current + value;
      }
 
      // 이 함수는 DOM 업데이트라는 사이드 이펙트를 담당하지만,
      // calculateNewTotal 함수와는 독립적으로 작동합니다.
      function updateDisplay(newTotal) {
        document.getElementById("currentTotalPure").textContent = newTotal;
        console.log(`[JS Pure] 화면 업데이트 완료. 현재 합계: ${newTotal}`); // DOM 업데이트 후 로그는 허용될 수 있습니다.
      }
 
      document.getElementById("incrementButtonPure").addEventListener("click", () => {
        const newTotal = calculateNewTotal(totalCountPure, 5); // 순수 함수 호출
        totalCountPure = newTotal; // 순수 함수의 결과를 받아 외부 상태 업데이트
        updateDisplay(totalCountPure); // DOM 업데이트
      });
 
      // 초기 렌더링
      updateDisplay(totalCountPure);
    </script>
  </body>
</html>

위 코드를 보면 calculateNewTotal 함수는 currentvalue라는 인자를 받아서 단순히 두 값을 더한 결과를 반환합니다. 이 함수는 외부의 totalCountPure 변수를 직접 수정하지 않으며, console.log와 같은 외부 시스템과의 상호작용도 포함하지 않습니다. totalCountPure 변수의 업데이트와 DOM 조작은 addEventListener 내부에서 calculateNewTotal 함수의 반환값을 이용해 이루어집니다. 이처럼 계산 로직과 UI 업데이트 로직을 분리함으로써, 우리는 자바스크립트 환경에서도 순수 함수의 장점을 어느 정도 활용할 수 있게 됩니다. 이는 코드의 예측 가능성을 높이고 테스트를 용이하게 하는 좋은 개발 관행입니다.

자바스크립트 (순수 함수 지향) 방식의 특징

  1. 역할 분리: '값 계산'과 'DOM 업데이트'라는 두 가지 역할을 별개의 함수로 명확히 분리하여, 계산 함수는 순수하게 유지하고 DOM 조작은 전담 함수에서 처리합니다.
  2. 순수 함수 활용: calculateNewTotal과 같이 주어진 입력에만 의존하고 외부 상태를 변경하지 않는 순수 함수를 사용하여 예측 가능성을 높입니다.
  3. 제한적인 사이드 이펙트: DOM 업데이트(updateDisplay)와 같은 사이드 이펙트는 발생하지만, 계산 로직과는 분리되어 관리되므로 이전 방식보다는 제어하기 용이합니다.
  4. 여전히 수동적인 UI 동기화: 순수 함수를 사용하더라도, 데이터 변경에 따른 UI 업데이트는 개발자가 명시적으로 호출해야 합니다. 자동화된 동기화는 이루어지지 않습니다.

리액트 (순수 컴포넌트): props와 선언형 UI

이제 리액트 버전으로 넘어가 보겠습니다. 리액트에서는 컴포넌트를 순수하게 유지하기 위해 외부로부터 props를 받아 UI를 렌더링하는 방식을 사용합니다. 앞서 살펴본 자바스크립트의 순수 함수 지향 코드와 비교해 볼 때, 리액트는 이러한 순수 함수 원칙을 컴포넌트 차원에서 더욱 쉽고 자연스럽게 적용할 수 있도록 돕습니다. 아래 예제는 이전 자바스크립트 예제와 동일하게 카운터 값을 표시하는 기능을 리액트로 구현한 것입니다. 여기서는 컴포넌트 내부에서 상태를 직접 관리하지 않고, props로 전달받은 totalCount 값을 단순히 화면에 보여주는 '순수한 렌더링'에 집중합니다.

JSX 버전

src/
├── components/
│   └── TotalCounter.jsx
└── App.jsx
└── main.jsx

src/components/TotalCounter.jsx (카운터 컴포넌트)

// TotalCounter 컴포넌트는 props로 totalCount와 onIncrement를 받습니다.
// 이 컴포넌트는 오직 받은 props에만 의존하여 UI를 렌더링하므로 순수합니다.
export default function TotalCounter({ totalCount, onIncrement }) {
  // 렌더링 중 사이드 이펙트(로그)는 지양합니다.
  // console.log(`[React] TotalCounter 렌더링 중. 현재 합계: ${totalCount}`);
 
  // 클릭 이벤트는 상위 컴포넌트로부터 받은 onIncrement 함수를 호출합니다.
  // 이 컴포넌트 자체는 상태를 변경하지 않습니다.
  const handleClick = () => {
    if (onIncrement) {
      onIncrement(); // 상위 컴포넌트의 로직을 실행하도록 위임합니다.
    }
  };
 
  return (
    <div>
      <h1>React Pure Component Example</h1>
      <p>
        현재 합계: <span>{totalCount}</span>
      </p>
      <button onClick={handleClick}>값 5 증가</button>
    </div>
  );
}

src/App.jsx (최상위 앱 컴포넌트)

import TotalCounter from './components/TotalCounter';
 
export default function App() {
  const initialCount = 0; // 초기값 설정
 
  // 이 예제에서는 상태 변경 로직이 없으므로 버튼을 눌러도 값이 변하지 않습니다.
  // 상호작용 가능한 상태 관리는 Part 3: 상호작용의 진화 - Adding Interactivity 에서 자세히 다룰 예정입니다.
  const handleIncrement = () => {
    alert(
      '아직 상태를 관리하고 있지 않아 값이 변하지 않습니다. Part 3에서 상호작용을 배우게 됩니다!'
    );
  };
 
  return <TotalCounter totalCount={initialCount} onIncrement={handleIncrement} />;
}

src/main.jsx (애플리케이션 진입점 파일)

import ReactDOM from 'react-dom/client';
import App from './App';
 
const rootElement = document.getElementById('root');
if (rootElement) {
  ReactDOM.createRoot(rootElement).render(
    <React.StrictMode>
      <App />
    </React.StrictMode>
  );
}

위 리액트 코드에서 TotalCounter 컴포넌트는 propstotalCountonIncrement를 받습니다. 이 컴포넌트는 자신의 props가 주어지면 항상 동일한 JSX(UI)를 반환하므로 순수합니다. 버튼을 클릭하면 onIncrement라는 props로 받은 함수를 호출하지만, TotalCounter 컴포넌트 자체는 어떤 상태도 직접 변경하지 않습니다. 현재 App 컴포넌트에서는 initialCount라는 정적인 값만 TotalCounter에 전달하고 있으며, onIncrement도 임시적인 alert 함수를 연결했습니다. 이는 우리가 아직 useState와 같은 리액트의 상태 관리 훅을 배우지 않았기 때문입니다. TotalCounter의 순수성에 초점을 맞춰, 외부에서 주어지는 props에 따라 예측 가능하게 렌더링되는 컴포넌트의 모습을 보여주고자 합니다.

무엇이 다른가? 첫 번째 자바스크립트 예제에서는 함수가 전역 변수를 직접 변경하고 DOM을 조작했습니다. 두 번째 자바스크립트 예제에서 계산 로직을 순수 함수로 분리했지만, 여전히 DOM 업데이트는 개발자가 직접 처리해야 했습니다. 리액트에서는 컴포넌트가 props를 입력으로 받아 UI를 선언적으로 반환함으로써 순수성을 확보합니다. UI 업데이트는 개발자가 직접 DOM을 조작하는 대신, 리액트에게 props가 변경되었음을 알려주면 리액트가 알아서 효율적으로 처리하게 됩니다. 이 과정에서 컴포넌트 함수의 순수성이 지켜지며, 개발자는 UI의 '모양(What)'에 집중할 수 있게 됩니다. 상호작용 가능한 동적인 UI를 만드는 방법은 Part 3: 상호작용의 진화 - Adding Interactivity 에서 useState 훅을 배우면서 자세히 다루게 될 것입니다.

리액트 (순수 컴포넌트) 방식의 특징

  • 1. 선언형(Declarative) UI와 예측 가능한 결과: 리액트 컴포넌트는 props를 입력으로 받아 '무엇을' 보여줄지 **선언적(Declarative)**으로 정의합니다. 이는 개발자가 DOM을 직접 조작하며 '어떻게'(How) UI를 변경할지 명령하는 방식(Imperative)과 대조됩니다. 컴포넌트는 오직 propsstate에만 의존하여 UI를 렌더링하므로, 동일한 입력이 주어지면 항상 동일한 UI 결과물을 보장합니다. 이러한 예측 가능성은 복잡한 애플리케이션에서 UI의 동작을 쉽게 추론하고, 버그 발생 가능성을 줄이며, 테스트 및 디버깅을 용이하게 하는 리액트의 핵심 철학입니다.
  • 2. 순수 컴포넌트 원칙과 책임 분리: 리액트 컴포넌트는 순수 함수와 같이, props를 입력으로 받아 JSX를 반환하며, 렌더링 과정에서 외부의 어떤 상태도 직접 변경하지 않습니다. 이는 컴포넌트의 주된 책임이 UI를 '표현하는 것'에 있음을 명확히 합니다. 이러한 순수성 원칙은 컴포넌트가 특정 props를 받았을 때 어떤 UI를 렌더링할지 쉽게 예상할 수 있게 하며, 컴포넌트 간의 결합도를 낮춰 재사용성과 유지보수성을 향상시킵니다. App 컴포넌트가 TotalCounter에게 props를 통해 데이터를 전달하고, TotalCounter는 이를 단순히 '표현'만 하는 것이 이러한 책임 분리의 좋은 예시입니다.
  • 3. UI 동기화의 자동화와 개발자의 부담 경감: TotalCounter 컴포넌트는 props로 받은 totalCount 값을 단순히 화면에 표시하고, 버튼 클릭 시에는 onIncrement 함수를 호출하여 상위 컴포넌트에게 상태 변경을 위임합니다. 이는 컴포넌트 자체적으로 DOM을 조작하거나 상태를 직접 변경할 필요가 없음을 의미합니다. 리액트는 propsstate의 변경을 감지하면, Virtual DOM을 통해 효율적으로 UI를 다시 렌더링하여 실제 DOM과 동기화하는 책임을 집니다. 개발자는 UI 업데이트의 '방법'에 대한 고민 없이, '어떤 상태일 때 무엇을 보여줄지'에만 집중할 수 있어 개발 생산성이 크게 향상됩니다.
  • 4. 사이드 이펙트의 엄격한 분리 및 관리: 리액트는 렌더링 과정에서 console.log나 네트워크 요청, DOM 직접 조작과 같은 사이드 이펙트가 발생하는 것을 지양합니다. 이러한 사이드 이펙트는 렌더링의 예측 불가능성을 높이고, 애플리케이션의 동작을 복잡하게 만들 수 있기 때문입니다. 대신 리액트는 useEffect와 같은 **전용 훅(Hooks)**을 제공하여 이러한 사이드 이펙트를 컴포넌트의 생명주기(Lifecycle) 시점(컴포넌트가 마운트되거나 업데이트될 때 등)에 맞춰 명시적으로 관리하도록 권장합니다. 이는 UI 렌더링 로직과 부수 효과 로직을 명확하게 분리하여 코드의 가독성, 안정성, 그리고 디버깅 용이성을 크게 향상시킵니다. (이 내용은 5-3편편에서 자세히 다룰 예정입니다.)
  • 5. 테스트 용이성 극대화: 순수 컴포넌트는 동일한 props가 주어지면 항상 동일한 UI를 반환하며 외부 상태에 영향을 미치지 않으므로, 테스트하기가 매우 용이합니다. 특정 props를 주었을 때 예상하는 JSX 결과물이 정확히 나오는지 검증하기만 하면 됩니다. 이는 UI 컴포넌트의 테스트 커버리지를 높이고, UI 변경 시에도 기존 기능의 회귀(regression)를 효과적으로 방지하는 데 결정적인 역할을 합니다. DOM 조작이나 외부 상태에 의존하는 컴포넌트보다 훨씬 더 견고하고 신뢰할 수 있는 UI를 구축할 수 있게 됩니다.

자바스크립트 vs 리액트 차이점 비교

세 가지 방식의 차이를 표로 정리해 보았습니다.

구분자바스크립트 (사이드 이펙트 포함)자바스크립트 (순수 함수 지향)리액트 (순수 컴포넌트)
개발 방식명령형(Imperative): '어떻게' 변경할지 지시 (2-1편 참조)명령형(Imperative): 역할 분리, '어떻게' 지시 (2-1편 참조)선언형(Declarative): '무엇을' 보여줄지 선언 (2-1편 참조)
상태 관리전역 변수 직접 수정, DOM 직접 조작외부 상태 직접 업데이트 (값은 순수 함수로 계산)props를 통한 외부로부터의 상태 전달 (내부 상태 없음)
함수의 순수성외부 상태 변경(사이드 이펙트) 허용계산 로직은 순수, DOM 조작은 분리된 사이드 이펙트순수 함수 지향: 외부 상태 변경 지양, 동일 입력-동일 출력
UI 업데이트개발자가 직접 DOM API로 업데이트개발자가 직접 DOM API로 업데이트props 변경에 따라 리액트가 자동으로 리렌더링
예측 가능성낮음: 외부 요인에 따라 결과 달라질 수 있음중간: 계산 로직은 예측 가능, UI 동기화는 수동높음: 동일 입력에 항상 동일한 결과 보장
사이드 이펙트함수 내에서 자유롭게 발생계산 로직에서 분리, DOM 업데이트에서 발생렌더링 과정에서 지양, useEffect로 분리 관리 (5-3편에서 자세히 다룹니다)

요약

이번 편에서는 예측 가능한 UI를 만들기 위한 핵심 개념인 '순수 컴포넌트 원칙'에 대해 살펴보았습니다. 자바스크립트 개발자로서 우리가 흔히 접했던 사이드 이펙트가 있는 코드, 순수 함수를 지향하는 자바스크립트 코드, 그리고 리액트의 순수 컴포넌트가 어떻게 다른지 비교하며, 왜 리액트가 순수 함수를 강조하는지 이해하는 시간이 되었기를 바랍니다. 지금까지 다룬 핵심 내용들을 다시 한번 정리해 보겠습니다.

  • 순수 함수: 동일 입력-동일 출력, 사이드 이펙트 없음
  • 사이드 이펙트: 함수 외부 상태 변경 작업
  • 자바스크립트 (사이드 이펙트 포함): 명령형 DOM 조작, 자유로운 사이드 이펙트, 낮은 예측 가능성
  • 자바스크립트 (순수 함수 지향): 계산-DOM 업데이트 역할 분리, 순수 함수 활용, 수동 UI 동기화
  • 리액트 (순수 컴포넌트): 선언형 UI, props 기반 렌더링, 높은 예측 가능성, useEffect로 사이드 이펙트 관리 (5-3편)
  • 예측 가능한 UI: 순수 컴포넌트 원칙 적용을 통한 안정성 및 유지보수성 향상

다음 편(2-7편)에서는 UI를 컴포넌트 트리 관점에서 이해하고, 렌더 트리와 의존성 트리가 어떤 역할을 하는지 살펴보겠습니다.

참고문서

– [컴포넌트를 순수하게 유지하기 (Keeping Components Pure)]