React에서 리렌더링은 컴포넌트 함수가 다시 실행되어 UI 결과를 다시 계산하는 과정입니다. 보통 state 변경, 부모 컴포넌트의 리렌더링, context 값 변경이 원인이 됩니다. 다만 리렌더링이 곧 실제 DOM 업데이트를 의미하지는 않습니다. React는 새 결과와 이전 결과를 비교한 뒤, 실제로 달라진 부분만 DOM에 반영합니다.
꼬리질문
조금 더 깊게 물어본다면
답변 뒤에 이어질 수 있는 질문들을 하나씩 열어볼 수 있어요.
리렌더링과 DOM 업데이트는 같은 말인가요?
같은 말이 아닙니다. 리렌더링은 React가 컴포넌트 함수를 다시 실행해서 다음 UI 결과를 계산하는 과정입니다. DOM 업데이트는 그 결과가 이전과 다를 때 실제 DOM에 반영하는 commit 과정입니다. 그래서 리렌더링은 발생했지만 실제 DOM 변경은 없을 수 있습니다.
부모가 리렌더링되면 자식은 무조건 리렌더링되나요?
기본적으로는 자식도 다시 렌더링될 수 있습니다. 다만 React.memo로 감싸고 props가 같다면 자식 렌더링을 건너뛸 수 있습니다. 여기서 중요한 건 “부모가 바뀌면 자식도 무조건 DOM이 바뀐다”가 아니라, 자식 함수가 다시 호출될 수 있다는 점입니다.
React.memo를 쓰면 항상 성능이 좋아지나요?
항상 좋아지지는 않습니다. React.memo도 props 비교 비용이 있고, props로 매번 새 객체나 새 함수를 넘기면 기대한 만큼 막지 못할 수 있습니다. 렌더링 비용이 큰 컴포넌트이거나 props가 안정적인 경우에 효과가 더 큽니다.
useCallback을 쓰면 리렌더링이 막히나요?
useCallback 자체가 리렌더링을 막지는 않습니다. 함수 reference를 안정적으로 유지해 줄 뿐입니다. 이 reference 안정성이 React.memo된 자식의 props 비교에 도움이 될 때 리렌더링을 줄이는 효과가 생깁니다.
state를 같은 값으로 setState하면 어떻게 되나요?
React는 이전 state와 다음 state를 비교해서 같은 값이면 렌더링을 건너뛸 수 있습니다. 다만 객체나 배열은 reference 기준으로 비교하기 때문에, 내용이 같아도 새 객체를 만들면 다른 값으로 판단될 수 있습니다.
부가 설명
처음에는 “state가 바뀐 컴포넌트만 다시 그려진다”고 생각하기 쉽습니다. 그런데 부모가 다시 렌더링되면 자식도 기본적으로 다시 렌더링될 수 있습니다. 이때 자식의 props 값이 같아 보여도 함수 컴포넌트는 다시 호출될 수 있습니다.