React 공식 문서를 읽다보면 useMemo
와 useCallback
훅을 최대한 지향하라는 말을 자주 볼 수 있다.
console.time
과 console.timeEnd
를 사용해서 소요된 시간을 측정하고 일반적으로 1ms 이상이면 useCallback
을 사용하라고 한다.useCallback
을 사용해서 최적화를 시도했으나 오히려 초기 렌더링에서는 시간이 더 소요되는 것을 알 수 있었다.useCallback
을 사용하면 리액트가 그 함수를 캐싱하기 때문이라고 생각한다.useCallback
을 최소화로 사용하라고 하는 것이다.useCallback
을 사용하라useCallback
파트에서 커스텀 훅 최적화 하기라는 파트를 읽어보면 다음과 같은 문장이 있다.커스텀 Hook을 작성하는 경우, 반환하는 모든 함수를 useCallback으로 감싸는 것이 좋습니다.
그럼 React에서도 최소한으로 사용하라 그런 useCallback
에서 반환하는 함수에서는 적극 권장할까?
하위 컴포넌트에게 함수를 props로 넘겨줄 때 하위 컴포넌트가 memo
(React.memo
)로 감싸 있어도 상위 컴포넌트에서 그 함수가 최적화가 되어 있지 않으면 최적화가 제대로 되지 않는다.
memo
로 감싸도 다른 참조값이 들어와서 문맥적으로는 같으나 다른 값이라고 인식하는 것이다.커스텀 Hook 에서 useCallback
으로 반환 함수를 감싸놨으면 반환된 함수를 Props로 넘겨도 리렌더링을 memo
로 감싼 컴포넌트에게는 부모가 리렌더링되어도 리렌더링을 유발하지 않는다.
useEffect
의 dependecies에 커스텀 Hook 에서 반환된 함수를 넣을때도 useCallback
으로 감싸져 있는 함수를 넣으면 useCallback
으로 감싼 함수의 dependecies가 변하지 않는 이상 재 실행이 되지 않으므로 같은 이유에서 useCallback
으로 감싸놓는 것이 좋다.
위의 최적화 관점에서 커스텀 Hook에서 useCallback
으로 반환되는 함수를 감싸면 좋다는 것을 알았는데 왜 React 문서에서 모든 함수를 감싸라는 것이 좋다는 것은 잘 이해가 되지 않을 것이다.
"모든"이라는 부분은 필자는 협업의 관점에서 생각했다.
useCallback
으로 감싸져 있나 찾아봐야한다.useCallback
을 감싸기로 약속해서 최적화할때 useCallback
으로 감싸져 있는지 여부를 신경쓰지 않아도 되게 미리 모든 반환함수는 useCallback
으로 감싸져 있다고 "예상 가능하게" 만드는 것이라고 생각한다.