한 프로젝트의 회원가입 폼 컴포넌트에서 문제점을 발견했다.
바로 모든 입력마다 회원가입 폼 컴포넌트와 관련된 컴포넌트들이 리렌더 되는 현상이다.
눈이 아플지경.
왜 이렇게 많은 렌더링이 일어날까?
리액트는 상태를 가진 컴포넌트의 상태가 변할 경우 리렌더 되고, 자식 컴포넌트들도 같이 리렌더링 된다.
이러한 구조를 가진 이유는 리액트의 특성상 상태 변화에 따른 UI 업데이트를 보장하기 위해서다.
그렇다면 부모 컴포넌트의 리렌더링이 반드시 자식 컴포넌트의 리렌더링을 유발해야 할까요? 피할 수 있는 방법이 있다.
React.memo
를 사용하면 부모 컴포넌트의 리렌더링에 의한 자식 컴포넌트의 리렌더링을 방지할 수 있다.
export const WarningMessage = React.memo((...) => {
return ...
});
import {memo, ...} from 'react';
export const CommonInput = memo((...) => {
return ...
});
하지만 React.memo
로 리렌더를 막아도, props
가 변경되면 자식 컴포넌트는 리렌더 된다.
<CommonInput
...
onChange={val => validateField('email', val)}
/>
위 코드에서 onChange
에 전달되는 validateField
함수가 문제다.
함수는 객체이며, 객체는 원시 데이터가 아니기 때문에 참조값으로 식별된다.