useCallback()

inside_6_·2024년 3월 12일

React_Hooks

목록 보기
6/10
post-thumbnail

개요

const cachedFn = useCallback(() => {
// fn...
}, [dependencies])

useCallback은 리렌더링 사이에 함수 정의를 캐시할 수 있게 해주는 React훅이다.

fn : 함수 자체를 memoization해준다. 함수가 필요할 때마다 메모리에서 가져와서 사용한다.
dependencies : 의존성 배열. 배열 안의 값이 변경되면 렌더링 된다.

렌더링은 함수형 컴포넌트 자체를 호출하여 모든 내부 변수가 초기화 된다.


활용예제

// UseCallbackstudy.js

function UseCallbackstudy() {
  const [size, setSizes] = useState(100);

	const createBoxStyle = () => {
		return {
			backgroundColor: "pink",
			width: `${size}px`,
			height: `${size}px`,
		};
	};

  return (
    <div>
      <input
        type="number"
        value={size}
        onChange={(e) => setSizes(e.target.value)}
      />
      <Box createBoxStyle={createBoxStyle} />
    </div>
  );
}

// Box.js

function Box({ createBoxStyle }) {
  const [style, setStyle] = useState({});

  useEffect(() => {
    console.log("박스 키우기 💅");
    setStyle(createBoxStyle());
  }, [createBoxStyle]);

  return <div style={style}></div>;
}

위의 예제는 input을 통하여 Box size가 바뀌면 콘솔이 찍히는 코드이다. input에서 값을 변환하면 그 값에 따라 Box의 크기가 변경되며 콘솔내용을 출력해준다. 이때 state값이 변하기 때문에 페이지는 렌더링이 되며 자식 컴포넌트에 해당하는 Box.js도 함께 렌더링 된다.

function UseCallbackstudy() {
  const [size, setSizes] = useState(100);
  const [isDark, setIsDark] = useState(false);

   const createBoxStyle = () => {
     return {
       backgroundColor: "pink",
       width: `${size}px`,
       height: `${size}px`,
     };
   };

  return (
    <div
      style={{
        background: isDark ? "black" : "white",
      }}
    >
      <input
        type="number"
        value={size}
        onChange={(e) => setSizes(e.target.value)}
      />
      <button onClick={() => setIsDark(!isDark)}>Change Theme</button>
      <Box createBoxStyle={createBoxStyle} />
    </div>
  );
}

Change Theme 버튼을 추가하여 배경색을 바꾸는 기능을 추가하였다. 그런데 해당 기능을 이용하면 상관없는 콘솔이 출력된다.

그 이유는 state의 변화가 있으니 다시 렌더링이 되어 createBoxStyle이 초기화되기 때문이다.

size가 바뀌었을때만 초기화 되도록 하기위해 useCallback을 활용해보겠다.

function UseCallbackstudy() {
  const [size, setSizes] = useState(100);
  const [isDark, setIsDark] = useState(false);
  
    const createBoxStyle = useCallback(() => {
    return {
      backgroundColor: "pink",
      width: `${size}px`,
      height: `${size}px`,
    };
  }, [size]);
  
  return (
    <div
      style={{
        background: isDark ? "black" : "white",
      }}
    >
      <input
        type="number"
        value={size}
        onChange={(e) => setSizes(e.target.value)}
      />
      <button onClick={() => setIsDark(!isDark)}>Change Theme</button>
      <Box createBoxStyle={createBoxStyle} />
    </div>
  );
};

useCallback의 의존성 배열에 size를 넣어서 size의 값이 바뀔 때만 "박스 키우기 💅" 콘솔이 호출되도록 했다.


useMemo() 와 useCallback()의 차이점

useMemo는 memoization된 을 반환하지만 useCallback은 memoization된 함수를 반환한다.
useMemo는 함수의 연산량이 많을때 이전 결과값을 재사용하는 목적이고, useCallback은 함수가 재생성 되는것을 방지하기 위한 목적이다.


적용점

아직 둘의 차이에 대해서 와닿지 않는다. 값을 반환하고 함수 자체를 반환하는 것에 대한 차이는 프로젝트를 통해 어떤식으로 작동하는지 직접 해보면서 학습하는게 빠를듯 하다.


참조

profile
한다. 프론트엔드.

0개의 댓글