본문 바로가기
React/개념

useCallback

by hihijh826 2024. 1. 5.
728x90
반응형
SMALL

📍 useCallback

- 함수를 기억했다가 재사용하도록 도와주는 훅

- 불필요한 리렌더링을 맊기 위해서 

 

☑️ 리렌더링이란

React의 리렌더링 조건은 간단하게 3가지이다.
1. 자신의 state가 변경될 때
2. 부모 컴포넌트로부터 전달받은 props가 변경될 때
3. 부모 컴포넌트가 리랜더링될 때

 

 

☑️ 사용법 

 

const cachedFn = useCallback(fn, [deps1, deps2... ])

 

  • fn 함수로  React가 첫 렌더링 시에 반환하며, 만약 deps가 바뀌지 않은 경우, 같은 함수를 계속해서 반환하게 돈다.
  • deps : 의존성 값으로 fn이 의존하는 값들의 배열이며, 유동적 값(reactive value)이면 어떤 것이든 상관없이 들어갈 수 있으며, 함수가 의존하는 값의 수만큼 개수가 많아질 수 있다.  이 의존성 값이 변경 되었을 때 리렌더링 한다.

 

const fetchMovieData = useCallback ( () => {

doSomething( );

},

[ 의존성 값],);

 

 

☑️ 사용예시 - Row.js 

 

const Row = ({ title, id, fetchUrl }) => {
  //title,id,fetchUrl을 props로 가져온 것임
  const [movies, setMovies] = useState([]);

  //컴포넌트가 렌더링 될 떄 마다 함수도 다시 새롭게 생성되는데 이것이 불필요함으로 콜백함수이용
  const fetchMovieData = useCallback(async () => {
    const response = await axios.get(fetchUrl);
    //console.log('response',response);
    setMovies(response.data.results);
  }, [fetchUrl]);

  useEffect(() => {
    fetchMovieData();
  }, [fetchMovieData]);
  //fetchUrl이 바뀌면 fetchMovieData도 변하기 때문에 다시 호출 해야됨

 

 

> fechUrl이 바뀌면 리렌더링해준다 

 

 

☑️ 사용예시 

데이터 fetching과 의존성을 가지는 경우

const Section1 = ({ onProjectClick }) => {
  const [popularProjects, setPopularProjects] = useState([]);

  // useCallback을 사용하여 fetchPopularProjects 최적화
  const fetchPopularProjects = useCallback(async () => {
    try {
      const response = await axios.get('/api/projects/popular'); // 인기 프로젝트 데이터 요청
      setPopularProjects(response.data);
    } catch (error) {
      console.error('Error fetching popular projects:', error);
    }
  }, []); // 의존성 배열이 비어 있으므로 컴포넌트가 마운트될 때만 호출됨

  useEffect(() => {
    fetchPopularProjects(); // 컴포넌트가 마운트될 때 데이터 가져오기
  }, [fetchPopularProjects]);

 

 

> 의존성 배열을 비어 있으므로 컴포넌트가 처음 렌더링 될때만 생성

> fetchPopularProjects가 변경될 때에만 useEffect가 다시 실행 

`useEffect`에서 호출되며, 컴포넌트가 마운트될 때 한 번만 실행됨

 

 

☑️ Usecallback을 사용하지 않으면? 

- 무한 루프 발생 가능성

- 불필요한 렌더링

- 의존성 관리 문제 

 

 

📍 Usecallback을 사용해야 될 때

 

컴포넌트가 자주 리렌더링 되거나 자식 컴포넌트에 함수를 전달해야 될 떄 

 

1. 자식 컴포넌트에 props로 함수 전달 시

자식 컴포넌트에 함수를 props로 전달할 때, 부모 컴포넌트가 리렌더링되면 자식 컴포넌트도 리렌더링될 수 있습니다.특히, 자식 컴포넌트가 React.memo로 최적화되어 있을 경우, useCallback을 사용하여 함수의 참조를 유지하면 불필요한 리렌더링을 방지할 수 있습니다.

2. 외부에서 값을 가져오 API 호출 시 의존성 배열 문제 해결

useEffect에 의존성 배열로 함수를 전달할 때, 그 함수가 매번 새로운 참조값으로 변경되면 무한 루프가 발생할 수 있습니다.useCallback을 사용하면 함수의 참조가 동일하게 유지되어, 의존성이 변경되지 않는 한 useEffect가 불필요하게 재실행되는 것을 방지합니다.

3.  custom hook에서 최적화

커스텀 훅을 만들 때, 내부에서 사용하는 함수가 자주 변경되지 않도록 useCallback을 사용하여 최적화할 수 있습니다.이를 통해 훅이 호출될 때마다 함수가 새로 생성되는 것을 방지합니다.

무한 루프를 피하는 대안

함수 바깥에 정의: 의존성으로 사용되는 함수가 바깥에 정의되어 있으면, 컴포넌트가 리렌더링될 때마다 새로운 참조값이 생성되지 않습니다. 그러나 이 방법은 함수가 바뀌어야 할 때 유연성을 잃을 수 있습니다.상태를 직접 사용: 상태 값이 변경될 때마다 그 상태를 직접 사용하는 방식으로, 새로 함수 객체를 생성하지 않고도 상태를 관리할 수 있습니다.

 

 

 

https://velog.io/@hae2ni/useCallback-useRef%EC%97%90-%EB%8C%80%ED%95%98%EC%97%AC-%ED%95%A8%EC%88%98%EC%9D%98-%EC%B5%9C%EC%A0%81%ED%99%94%EC%99%80-DOM-%EB%B6%88%EB%9F%AC%EC%98%A4%EA%B8%B0%EB%A5%BC-%ED%86%BA%EC%95%84%EB%B3%B4%EC%9E%90

 

 



 

728x90
반응형
LIST

'React > 개념' 카테고리의 다른 글

[리액트] 컴포넌트 및 기초사항  (0) 2024.01.12
#6 props - row.js  (0) 2024.01.12
$ 사용  (0) 2024.01.05
#4 React 이벤트 처리(리스너, onClick(핸들링 이벤트)  (0) 2024.01.05
#2 리액트 컴포넌트  (0) 2024.01.04