컴포넌트를 재실행 하는 경우
마지막 경우, props가 변경되지 않은 자식 컴포넌트는 부모 컴포넌트가 리렌더링이 된다 해도 다시 렌더링할 필요가 없다
=> memo 사용
memo는 컴포넌트의 props를 메모리에 저장하고 있다가 부모 컴포넌트가 리렌더링이 될 때, 저장한 props와 현재 props를 비교해서 다른 경우에만 리렌더링을 하도록 한다
function childComponent(props) {
...
}
export default React.memo(childComponent)
자주 값이 변경되지 않는 가장 최상단 컴포넌트에 적용을 해야 그것의 자식 컴포넌트에도 반영이 되므로 더 효율적이다
만약 props로 함수를 전달했다고 하자. JS에서 함수는 객체이고, 객체는 렌더링이 될 때마다 기존 메모리 위치에서 사라지고 새로운 메모리에 할당되어 props가 바뀌었다고 React가 간주한다
이때 함수를 useCallback으로 감싸주면 React는 그 함수를 저장하고, 의존 배열에 넘겨준 값이 변경될 때에만 함수를 재생성한다. 즉 의존 배열에 넘겨준 값이 변경될 때에만 리렌더링이 된다.
만약 배열에 아무 값도 전달하지 않으면 처음 함수가 생성되고 더이상 함수가 바뀌지 않음 -> 항상 같은 함수 props를 받는 경우 유용하다
function parentComponent () {
const func = useCallback(() => {
...
}, []);
return (
<ChildComponent propFunc={func} />
)
}
// Child
const ChildComponent = (props) => {
return <Button onChange={props.propFunc} />
}
useCallback이 함수를 기억한다면, useMemo는 값을 기억한다. 정확히는 배열, 객체 등 렌더링이 될 때마다 메모리가 해제되고 재할당되는 값을 기억한다.
function parentComponent () {
const [arr, setArr] = useState([5, 3, 1, 2, 4])
return (
<ChildComponent items={arr} />
)
}
// Child
const ChildComponent = (props) => {
const items = props.items
const listItems = useMemo(() => items, [items]);
return <div>listItems</div>
}
-> Child로 들어온 items가 변경될 때만 listItems가 바뀌어 자식 컴포넌트가 재렌더링, 아니면 기존 배열을 그대로 사용