시나리오
React Memo를 사용할 때 같이 이야기가 나오는 친구가 바로 useCallback이다
그래서 useCallback을 사용할 때와 사용하지 않은 함수를 비교한다.
머리론, useCallback이 의미없이 사용되면 일반 함수보다 시간이 더 오래 걸릴 거라는 생각이 들었다.
작업
import React, { useState } from "react";
import { useCallback } from "react";
import styled from "styled-components";
const ChildComponentOne = ({ photos }) => {
  console.log("ChildComponentOne Render");
  const handleClick1 = useCallback(() => {
    console.log("클릭");
  }, []);
  const handleClick2 = useCallback(() => {
    console.log("클릭");
  }, []);
  const handleClick3 = useCallback(() => {
    console.log("클릭");
  }, []);
  const handleClick4 = useCallback(() => {
    console.log("클릭");
  }, []);
  const handleClick5 = useCallback(() => {
    console.log("클릭");
  }, []);
  return (
    <ChildWrapper>
      {photos.map((photo) => (
        <p key={photo.id} onClick={handleClick1}>
          테스트
        </p>
      ))}
    </ChildWrapper>
  );
};
const ChildWrapper = styled.div`
  width: 45%;
  padding: 10px;
`;
export default ChildComponentOne;
ChildComponentOne의 경우 useCallback을 사용해서 의미없이 함수를 만들어봤다.
import styled from "styled-components";
const ChildComponentTwo = ({ photos }) => {
  console.log("ChildComponentTwo Render");
  const handleClick1 = () => {
    console.log("클릭");
  };
  const handleClick2 = () => {
    console.log("클릭");
  };
  const handleClick3 = () => {
    console.log("클릭");
  };
  const handleClick4 = () => {
    console.log("클릭");
  };
  const handleClick5 = () => {
    console.log("클릭");
  };
  return (
    <ChildWrapper>
      {photos.map((photo) => (
        <p key={photo.id} onClick={handleClick1}>
          테스트
        </p>
      ))}
    </ChildWrapper>
  );
};
const ChildWrapper = styled.div`
  width: 45%;
  padding: 10px;
`;
export default ChildComponentTwo;
ChildComponentTwo의 경우 일반적인 함수이다.
ChildComponentOne과 ChildComponentTwo는 비교군이다.
const ParentsComponents = () => {
  const [text, setText] = useState("");
  const [photos, setPhotos] = useState([]);
  useEffect(() => {
    fetch("https://jsonplaceholder.typicode.com/photos")
      .then((response) => response.json())
      .then(setPhotos);
  }, [setPhotos]);
  return (
    <div>
      <input value={text} onChange={(e) => setText(e.currentTarget.value)} />
      <Wrapper>
        <ChildComponentOne photos={photos} />
        <ChildComponentTwo photos={photos} />
      </Wrapper>
    </div>
  );
};
마지막으로 리렌더링을 발생시키기 위한 input과 각 컴포넌트를 호출시켜주는 ParentsComponent이다.
정리하면
ParentsComponent에서 text라는 State를 변경시키면
자식 컴포넌트인 ChildComponentOne과 ChildComponentTwo는 리렌더링이 발생한다.
이때, useCallback이 과연 리렌더링의 성능에 영향을 주는지 확인해봤다.


몇가지 더 예시가 있지만 결과적으로 큰 차이는 없었다.
물론 더 좋은 비교 방식이 있을 수 있지만 당장 눈에 보이는 비교 방식으로는 차이를 발견하지 못했다.
결과
useCallback을 남용을 한 컴포넌트와 일반 함수를 사용한 컴포넌트를 비교했을 때,
Profiler를 사용한 렌더링 속도 차이는 비교할 수 없었다.
후기
이런 방식으로 비교하는 것이 맞는지는 모르겠다.
하지만 지금 내가 알고있는 비교 방식으로는 차이가 없다는 결과가 나왔다.
이 외에도 다양한 시도 방법이 떠오르면 다시 한번 비교를 해보겠다.
'React > 실험실' 카테고리의 다른 글
| [React] 제어 컴포넌트 vs 비제어 컴포넌트 (0) | 2022.11.03 | 
|---|---|
| [React] useMemo vs useRef (0) | 2022.11.02 | 
| [React] React와 Canvas를 사용해서 움직이는 공 만들기 (1) | 2022.10.20 | 
| [React] React Query - 기존 상태 관리 라이브러리의 단점 (0) | 2022.10.17 | 
| [React] Redux와 TypeScript 함께 사용하기 (1) | 2022.10.12 | 
