DEV Community

wes5510
wes5510

Posted on

리액트에서 props가 수정되면 컴포넌트가 리랜더링 될까? 과연?

예전에 문득 React 공식 문서를 읽다가 흥미로운 내용을 발견했습니다.

Step 1: Trigger a render
There are two reasons for a component to render:

  1. It’s the component’s initial render.
  2. The component’s (or one of its ancestors’) state has been updated.

자세히 읽어보니 랜더링 트리거 조건 중 "props가 변경된 경우"에 대한 언급이 없었습니다. 이전까지 "props가 변경되면 컴포넌트가 렌더링된다"라고 생각했었는데, 문서에는 그와 관련된 내용이 없어 궁금증이 생겼습니다. "실제로 prop가 수정되면 컴포넌트가 렌더링되는가?"에 대한 실험을 진행하기로 결정했습니다.

정의

먼저 "props가 변경되면 컴포넌트가 렌더링된다"라는 가정에서 시작하여, props가 변하는 것과 컴포넌트가 렌더링되는 것 두 가지를 분리하여 고려해봅시다.

컴포넌트 렌더링

React 공식 문서에 따르면 컴포넌트 렌더링은 해당 컴포넌트를 호출하는 것입니다. 아래의 예제를 살펴보겠습니다.

Counter 컴포넌트는 onClick과 count라는 두 개의 props를 가지고 있습니다.

function Counter({
  onClick,
  count,
}) {
  return (
    <div>
      <button onClick={onClick}>카운트 올려!</button>
      <div>{`count : ${count}`}</div>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

이 Counter 컴포넌트를 상태값인 count로 가지고 있는 StateCounter 컴포넌트를 살펴보겠습니다.

let stateCounterRenderCount = 0;

function StateCounter() {
  stateCounterRenderCount += 1;

  const [count, setCount] = useState<number>(0);

  const handleClick = () => {
    setCount((prev) => prev + 1);
  };

  return (
    <div>
      <Counter count={count} onClick={handleClick} />
      <div>{`StateCounter 컴포넌트 렌더링 횟수: ${stateCounterRenderCount}`}</div>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Counter 컴포넌트의 버튼을 클릭하면 count 상태가 증가하고, StateCounter 컴포넌트의 렌더링 횟수도 증가합니다.
run StateCounter

이때 렌더링 횟수가 2번씩 증가하는 이유는 React 공식 문서에서 확인할 수 있습니다.

Components breaking this rule behave unpredictably and cause bugs. To help you find accidentally impure code, Strict Mode calls some of your functions (only the ones that should be pure) twice in development.

Strict Mode에서 순수 함수인지 디버깅하기 위해 의도적으로 함수를 두 번 호출합니다. 따라서 state를 수정할 때마다 stateCounterRenderCount가 2씩 증가합니다.

Props 수정

이제 렌더링에 영향을 미치는 다른 요소들은 배제하고, Counter 컴포넌트를 가지고 있는 PropsCounter 컴포넌트를 살펴보겠습니다.

let propsCounterRenderCount = 0;
let count = 0;

function PropsCounter() {
  propsCounterRenderCount += 1;

  const handleClick = () => {
    count += 1;
    console.log({ count }); // count가 실제로 증가하는지 확인하기 위한 콘솔 로그
  };

  return (
    <div>
      <Counter count={count} onClick={handleClick} />
      <div>{`PropsCounter 컴포넌트 렌더링 횟수: ${propsCounterRenderCount}`}</div>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Counter 컴포넌트의 버튼을 클릭하여 count를 증가시켜도 콘솔에는 count가 증가하지만 PropsCounter 컴포넌트의 렌더링 횟수는 증가하지 않습니다.
run PropsCounter

결론

props가 수정되어도 렌더링이 자동으로 발생하지 않습니다. 렌더링이 트리거되는 순간은 리액트 공식 문서에서 설명한 대로 다음과 같습니다:

  1. 컴포넌트의 초기 렌더링
  2. 컴포넌트(또는 상위 컴포넌트 중 하나)의 상태가 변경되었을 때

즉, props가 변경되더라도 렌더링은 상태의 변화에 의해 주로 발생하며, props의 변경으로 인한 렌더링은 해당 props가 컴포넌트 내부에서 상태로 사용되고 상태가 변경될 때 발생합니다.

Top comments (0)