본문 바로가기

프론트엔드/Java Script

JavaScript Sec05_9 최적화 3 - useCallback

  • 컴포넌트 코드가 길 때 React.memo를 이렇게도 사용할 수 있음

DiaryEditor 컴포넌트를 React.memo로 묶어서 내보내겠다는 뜻

useCallback


  • 일기 데이터의 상태가 변화할 때마다 App 컴포넌트가 리렌더 되고 그에 따라 자식 컴포넌트인 DiaryEditor 컴포넌트도 리렌더 된다. 이 때 DiaryEditor에 useMemo를 씌워도, 비원시타입 비교 시 얕게 비교하는 React.memo의 속성 때문에 App 컴포넌트가 리렌더 될 때마다 onCreate함수도 다시 만들어지고 그 새롭게 만들어진 onCreate 함수가 prop으로 Editor 컴포넌트에게 전달되므로 Editor 컴포넌트가 리렌더 된다.

⇒ onCreate 함수가 재생성되지 않아야만 DiaryEditor 컴포넌트를 최적화 할 수 있다!

  • useEffect, useMemo와 비슷하게 첫번째 인자로는 콜백함수, 두번째 인자로는 dependency array를 받는다.
  • useCallback은 useMemo와는 다르게 값을 반환하는 게 아니라 메모리제이션 된 콜백함수를 반환한다.
  • 의존성 배열의 값이 변화하지 않으면 첫번쨰 인자로 전달한 콜백함수를 계속 재사용 할 수 있도록 해 준다.

  • 의존성 배열로 빈 배열을 전달하면 mount 되는 시점에 콜백함수를 호출해 DiaryEditor 컴포넌트를 한 번만 만들고 그 다음부터는 기존의 콜백함수를 그대로 재사용 하겠다는 뜻이다.
  • 의존성 배열에 빈 배열을 전달하면 새로운 일기를 작성했을 때 기존의 20개의 일기가 사라지고 새롭게 작성된 1개의 일기가 일기 리스트에 보인다.
    • why? onCreate함수는 App 컴포넌트가 mount되는 시점에 한 번만 생성되었기 때문에 그 당시의 data state는 빈 배열 [] 이다. 즉, onCreate 함수는 callBack에 갇혀서, onCreate가 알고 있는 data 값 빈 배열인 것이다.
    • 새로운 일기를 작성하고 onCreate를 호출하면 setData([newData], …data)에서 data는 [] 인 것이다.
    • 이와 같은 문제를 해결하기 위해 함수형 업데이트를 사용한다.

함수형 업데이트


setState함수 인자에 값을 넣는 것이 아니라 콜백함수를 넣는 것을 의미한다.

setData((data)⇒[newData, ...data]);
  • 인자로 전달한 data를 통해 최신의 data값을 참고할 수 있다.