프론트엔드 첫걸음

useCallback으로 함수 재생성 방지하기 본문

개발 공부/React

useCallback으로 함수 재생성 방지하기

차정 2022. 8. 4. 15:36

useCallbak -

함수를 리액트 내부저장공간에 저장해서 함수객체가 실행될 때마다 재사용하도록 할 때 useCallback을 사용한다.

 

import React, { useState, useCallback } from 'react';

import Button from './components/UI/Button/Button';
import DemoOutput from './components/Demo/DemoOutput';
import './App.css'

function App() {
  const [showParagraph, setShowParagraph] = useState(false);
  const [allowToggle, setAllowToggle] = useState(false);
    
  console.log('App running')
  
  const toggleParagraphHandler = useCallback(() => {
    if(allowToggle){
      setShowParagraph((prevShowParagraph)=> !prevShowParagraph);
    }   
  }, [allowToggle]);// toggleParagraphHandler에서 allowToggle이 함수의 외부인자이고, allowToggle이 바뀌면 함수도 바뀌어야하므로 배열에 넣어주었다.


  
  const AllowtoggleHandler = () => {
    setAllowToggle(true);
  };
  
  return (
    <div className="app">
      <h1>Hi there</h1>
      <DemoOutput show={false}/>
      <Button onClick={AllowtoggleHandler}> Allow Toggling! </Button>
      <Button onClick={toggleParagraphHandler}> Toggle Paragraph! </Button>
    </div>
  )

}

 

useCallback으로 함수를 감싸주면 된다.
App 컴포넌트가 다시 렌더링 되어도 항상 같은 함수객체가 사용된다.

함수의 두번째 인자로 의존성 배열을 넣어 준다. 
함수의 외부 인자로 인해 함수가 바뀌는 경우 함수 또한 바뀌어야 하기 때문에 함수의 외부인자를 배열 안에 넣어준다

 

 

Fetch 함수 사용 

  function fetchMoviesHandler() {
    fetch('https://swapi.dev/api/films/')
      .then((response) => {
        return response.json();
      })
      .then((data) => {
        const transformedMovies = data.results.map((movieData) => {
          return {
            id: movieData.episode_id,
            title: movieData.title,
            openingText: movieData.opening_crawl,
            releaseDate: movieData.release_date,
          };
        });
      });
    setMovies(transformedMovies);
  }

 

async await 사용

  async function fetchMoviesHandler() {
    const response = await fetch('https://swapi.dev/api/films/');
    const data = await response.data();
    const transformedMovies = data.results.map((movieData) => {
      return {
        id: movieData.episode_id,
        title: movieData.title,
        openingText: movieData.opening_crawl,
        releaseDate: movieData.release_date,
      };
    });
    setMovies(transformedMovies);
  }

 

 

화면이 로딩되자마자 fetch 하도록 useEffect 사용 
useEffect 안에 함수 넣으면 무한 반복되니까 useCallback 사용

  const fetchMoviesHandler = useCallback(async () => {    
      const response = await fetch('https://swapi.dev/api/films/');  
      const data = await response.json();

      const transformedMovies = data.results.map((movieData) => {
        return {
          id: movieData.episode_id,
          title: movieData.title,
          openingText: movieData.opening_crawl,
          releaseDate: movieData.release_date,
        };
      });
      setMovies(transformedMovies);
 
  }, []);