지난 포스팅에서 아래 heavySum이라는 작업을 관련 없는 State가 업데이트 되었을 때는 실행되지 않도록 해서 성능을 개선했다.
하지만 아래 코드의 문제점은 ChildComponent가 props가 바뀌지 않았는데도 계속 리랜더된다는 점이었다. 이런 문제점을 해결하기 위한 방법은 없을까
export default function BlogComponent() {
const [num1, setNum1] = useState(0);
const [num2, setNum2] = useState(0);
const [num3, setNum3] = useState(0);
const heavySum = (a, b) => {
console.log("😅 무거운 작업");
return a + b;
};
const memoSum1 = useMemo(() => heavySum(num1, num2), [num1, num2]);
const memoSum2 = useMemo(() => heavySum(num2, num3), [num2, num3]);
return (
<div>
<button onClick={() => setNum1((prev) => prev + 1)}>
num1 + 1
</button>
<button onClick={() => setNum2((prev) => prev + 1)}>
num2 + 1
</button>
<button onClick={() => setNum3((prev) => prev + 1)}>
num3 + 1
</button>
<ChildComponent label="sum1" value={memoSum1} />
<ChildComponent label="sum2" value={memoSum2} />
</div>
);
}
const ChildComponent = ({ label, value }) => {
console.log(`re-rendered! label: ${label} value: ${value()}`);
return <p>{`label: ${label} value: ${value()}`}</p>;
};
props가 바뀌지 않았을 때 해당 component가 리랜더 되지 않도록 하기 위해서는 memo를 사용하면 된다. useMemo가 함수의 연산결과를 메모리에 저장해두고 사용하듯이 memo의 경우 component를 다시 랜더링 하지 않고 메모리에 저장된 것을 가져와서 사용한다.
아래 예시 코드처럼 component를 React.memo로 감싸주면 props가 변하는 경우에만 리랜더링 되는 것을 확인할 수 있다.
const ChildComponent = React.memo(({ label, value }) => {
console.log(`re-rendered! label: ${label} value: ${value}`);
return <p>{`label: ${label} value: ${value}`}</p>;
});