React.useCallback 후크를 사용하는 경우

useCallback 후크에 대해 처음 읽었을 때 저는 React 앱의 성능을 최적화할 수 있는 훌륭한 무기가 있다고 생각했고 제한 사항을 이해하지 못한 채 모든 망할 기능에 사용하기 시작했습니다.

이 항목에 대해 자세히 알아보기 전에 먼저 useCallback 후크가 정확히 무엇인지 대략적으로 이해하겠습니다.

따라서 기본적으로 useCallback 후크는 함수와 종속성 배열을 사용합니다. 메모이제이션된 함수를 반환합니다. 종속성 배열에 있는 요소의 값이나 참조가 변경될 때마다 이 함수의 메모화된 새 값이 생성됩니다.

useCallback 을 사용하여 함수를 래핑하지 않으면 어떻게 됩니까?



함수를 useCallback 로 래핑하지 않으면 구성 요소가 다시 렌더링될 때마다 함수의 새 인스턴스가 생성됩니다(함수에 새 메모리 위치가 지정됨).

또한 아래 스니펫을 기록해 두십시오.

function add() {
  return (a, b) => a + b;
}
const add1 = add();
const add2 = add();

add1(1, 2); // 3
add2(1, 2); // 3

add1 === add2; // false


위의 스니펫에서 add1 및 add2가 동일한 함수 선언에서 생성되고 동일한 출력을 제공하지만 이 두 함수의 참조가 다르기 때문에 동일하지 않음을 알 수 있습니다.

언제 useCallback 을 사용합니까?



예를 들어 보겠습니다.

function Child({ handler }) {

  return (
    <div onClick={handler}>
        Click Me
    </div>
  );
}

export default React.memo(Child)


아래는 상위 구성 요소입니다.

export default function ParentComponent() {
  const [state, setState] = useState(false);
  const [dep] = useState(false);

  const handler = useCallback(
    () => {
      console.log("You clicked handler")
    },
    [dep]
  );
  const statehanddler = () => {
    setState(!state);
  };
  return (
    <>
      <button onClick={statehanddler}>State Change</button>
      <Child handler={handler} />
    </>
  );


위의 예에서 하위 구성 요소를 React.memo로 래핑했습니다. 즉, 하위 구성 요소에 대한 소품이 변경되는 경우에만 하위 구성 요소를 다시 렌더링합니다.
handler는 자식 구성 요소에 소품으로 전달됩니다.

위의 예에서 useCallback를 사용하지 않았다고 가정해 보겠습니다.

이 경우 상태 변경 버튼을 클릭할 때마다 값state이 변경되고 상위 구성 요소가 다시 렌더링됩니다. 다시 렌더링할 때마다 생성된 모든 함수의 새 인스턴스가 있으므로 핸들러 함수의 새 인스턴스를 갖게 됩니다.

이제 자식 구성 요소는 어떻게 됩니까? 다시 렌더링됩니까?
add 예제에서 함수 동등성이 어떻게 작동하는지 보여 주었습니다. 이를 참조하면 handler 소품에 이제 새 참조가 있으므로 하위 구성 요소가 다시 렌더링될 것이라고 말할 수 있습니다. 이는 구성 요소를 React.memo로 래핑하더라도 하위 구성 요소를 다시 렌더링한다는 의미입니다.
useCallback를 사용한다고 가정합니다.
useCallback 여기 후크는 인수로 전달된 함수를 메모화하고 종속성 배열의 요소에 대한 참조 또는 값이 변경되는 경우에만 메모화된 함수의 새 인스턴스를 만듭니다.

따라서 상태 변경 버튼을 클릭하면 상태 변수state의 값이 변경되지만 종속성 배열(dep) 내의 값은 동일하게 유지됩니다. 따라서 핸들러의 새 인스턴스가 생성되지 않으며 자식 구성 요소가 다시 렌더링되지 않습니다.

useCallback 을 사용하지 않는 경우는 언제입니까?


useCallback 자체 단점이 있습니다. useCallback를 사용하는 것이 의미가 없는 경우가 있습니다.

예를 들어보자

export default function Parent() {

  const clickHandler = useCallback(() => {
      console.log('Click event')
  }, [])

  return <Child onClick={clickHandler} />
}

const Child = ({ clickHandler }) => {
  return <button onClick={clickHandler}>Child Component</button>
}


위의 예에서 useCallback를 사용하는 것은 모든 리렌더링에서 clickHandler 함수를 생성하기 때문에 의미가 없습니다. 또한 최적화는 매번 다시 렌더링할 때마다 수행해야 하는 useCallback 검사 때문에 비용이 더 많이 들 수 있습니다(인라인 함수 재생성은 일반적으로 저렴합니다).

결론


useCallback 렌더링할 때마다 재생성되지 않도록 값 대신 함수를 메모합니다. 불필요한 재 렌더링을 피하고 성능을 향상시키는 데 도움이 됩니다.

또한 useCallback를 사용하기 전에 구성 요소를 잘 스캔하지 않으면 비용이 많이 들 수 있으므로 사용하는 동안 주의해야 합니다.

이게 도움이 되길 바란다. 질문이나 제안 사항이 있으면 Github 및 (으)로 저에게 연락하십시오.

날 따라와

좋은 하루 되세요 :)

좋은 웹페이지 즐겨찾기