useCallback

CGH96·2022년 12월 29일
0

react

목록 보기
1/4

useCallback은 특정 함수의 참조값을 저장해놓고(Memoization), 그 참조값이 변할 때만 다시 호출 해줌.

먼저 이 코드를 보자.(youtube채널 별코딩의 영상을 보고 정리함)
useCallback

state의 number값을 출력해주는 someFunction함수가 있고, someFunction의 참조값이 변할 때마다 someFunc의 상태를 알려주기 위해 useEffect사용했다.

얼핏 보기엔 useEffect를 사용했기 때문에 state의 number값을 바꾸면 someFunction이 변하거나 재호출 된 것이 아니기 때문에 someFunction가 호출되지 않을 것 같다.


0부터 7까지 순차적으로 값을 올려보았다.

콘솔창을 확인해보면 number가 변한 만큼 someFunc가 리렌더링 되었다.

왜 그런 것일까???

이를 알기 위해서는 리액트의 렌더링 방식js의 객체를 참조하는 방식을 알아야 한다.

리액트의 렌더링 방식

리액트는 컴포넌트의 state나 props가 변하면 리렌더링 된다. 리렌더링된 컴포넌트의 자식 컴포넌트들도 모두 리렌더링 된다.

예들들어 Component A > B > C > D가 있다고 해보자.

  1. B의 props 혹은 State가 변화한다면 B의 리렌더링이 렌더링 큐에 들어간다.
  2. 리액트는 트리 최상단부터 rendering path를 시작한다.
  3. A는 렌더링이 필요하지 않기 때문에 지나간다.
  4. B는 업데이트가 필요한 컴포넌트로 체크되어 있기 때문에, B를 리렌더링 한다. B는 C를 리턴한다.
  5. C는 원래는 업데이트가 필요하지 않지만 부모컴포넌트인 B가 리렌더링 되었기 때문에 C도 리렌더링한다.
  6. D도 C와 마찬가지다.

js의 객체 추가 방식

예들 들어 const obj = { ... }라는 코드가 있다고 하자. 여기서 obj라는 변수는 객체를 직접 갖고있지 않다. 객체는 다른 위치에 저장되고, obj는 그 객체가 저장되어 있는 주소를 저장한다. 이런 특성 때문에 js에서 객체를 참조값이라고 한다.

따라서 위 코드에서는 App의 state가 변하므로 매번 App이 update 되고, App내부의 모든 변수들은 당연히 초기화가 된다. 그리고, someFunction이 참조할 화살표 함수의 참조값도 당연히 변한다.

그래서 number를 update할 때마다 App도 리렌더링 되고, App의 member들의 값도 변하는 것이다. 따라서 someFunction의 참조값도 변하게 된다.

그럼 어떻게 해야 할까??

이 때를 위해 필요한 것이 useCallback이다.


useCallback의 두번째 인자의 배열은 의존성 배열로, 이 배열 안의 요소가 update될 때만 이 함수가 다시 생성되도록 한다.

하지만 지금은 빈 배열이기 때문에 App이 처음 렌더링 될 때 생성된 함수가 저장되고, 그 뒤로는 이 함수가 초기화되어 재생성 되지 않는다. (처음 생성된 함수를 계속 재활용 한다.)


초기 렌더링 때 생성된 함수를 저장하여 쓰는 것이기 때문에 number의 값을 아무리 변경해도 처음 0값만 계속 출력한다.

0개의 댓글