선수지식 : 함수 컴포넌트는 렌더링 될때마다 전체가 재실행됨
useMemo: 복잡한 함수 결괏값을 기억한다. (메모이제이션된 값을 반환)
Hooks는 전체가 재실행되기 때문에 값이 잘 변하지 않는 실행이 오래걸리는 함수의 값을 기억
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
두 번째 인자인 배열에 있는 값이 바뀔때만 재실행 한다.
예시
import { useState, useMemo } from 'react';
function expensiveFunc() {
// ...
}
// 컴포넌트 가 계속 재실행됨 실행이 오래걸리는 함수가 있으면
// 값을 기억해서 렌더링 속도를 줄일 수 있음
const Component = () => {
// 예제는 최초 렌더링 되었을때만 함수를 실행한다.
const result = useMemo(() => expensiveFunc(), []);
const [value, setValue] = useState(result);
return (
// ...
)
}
export default Component;
useCallback: 함수 자체를 기억한다.
const memoizedCallback = useCallback(
() -> {
doSomething(a, b);
},
[a, b]
);
useCallback도 두 번째 인자인 배열에 있는 값이 바뀔때만 재실행 된다.
예시
import { useState, useCallback } from 'react';
const Component = () => {
const [state, setState] = useState(...);
// 함수 자체를 기억함
const expensiveFucn = useCallback(() => {
// ...
// state가 바뀔때 함수가 재실행됨
// 만약 state가 바뀌지 않으면 함수 안에 있는 값도 바뀌지 않음
}, [state]);
return (
// ...
)
}
export default Component;
자식컴포넌트에게 함수를 props로 넘길 때는 필수로 useCallback을 해줘야 된다.
이유
useCallback이 없으면 매번 새로운 함수가 실행이되는데, 자식컴포넌트에 매번 새로운 함수가 전달되면 부모로 부터 받은 props가 바뀌었다고 인식되었으므로, 자동으로 리렌더링이 된다.