[React.js] hook(3)-useCallback

apro_xo·2021년 11월 16일
0
post-thumbnail

useCallback vs useMemo

useCallbackuseMemo와 상당히 비슷한 hook이다.

useMemo, useCallback 둘 다 렌더링 성능 최적화에 사용된다.

useMemo는 어떤 특정한 값이 바뀌지 않으면 이전에 연산했었던 을 그대로 가져가는 것이고, useCallback도 비슷하게 이전에 생성되었던 함수 를 새로 생성하지 않고 계속 사용하게 해주는 함수이다.

함수들은 컴포넌트가 리렌더링 될 때마다 새로 만들어진다

따라서 규모가 큰 프로젝트에서 불필요한 함수 재생성은 리소스를 낭비하기 때문에 최적화를 해주어야 한다.

useCallback 사용 예시

기본적인 사용 방법은 아래와 같다.

const func=useCallback(()=>{ function or logic },[ value ]);

첫 번째 파라미터에는 생성하고 싶은 함수를 넣고, 두 번째 파라미터에는 배열을 넣는데, 이 배열에는 어떤 값이 바뀌었을 대 함수를 새로 생성해야하는지 명시해야한다.

import React, { useState, useCallback, useRef } from 'react';
const App = () => {
  const onInsert = useCallback((text) => {
    const todo = {
      id:nextId.current,
      text,
      checkd:false
    }
    setTodos(todos.concat(todo));
    nextId.current+=1;
  }, [todos])

  const onRemove = useCallback((id)=> {
    setTodos(todos.filter(todo=>todo.id !== id));
  }, [todos])

  const onToggle = useCallback((id)=> {
    setTodos(todos
    .map(todo=>todo.id === id ? {...todo, checked: !todo.checked} : todo))
  }, [todos]);
  
  return (
    <TodoTemplate>
      <TodoInsert onInsert = {onInsert}/>
      <TodoList todos={todos} onRemove={onRemove} onToggle={onToggle}/>
    </TodoTemplate>
  );
}

따라서 위와 같이 onInsert, onRemove, onToggle 함수를 보면 todos의 값이 바뀔 때 마다 코드의 로직대로 함수가 다시 재생성된다.

함수 내부에서 상태 값에 의존해야 할 때는 그 값을 반드시 두 번째 파라미터에 명시해야한다.

예를 들어, onInsert는 기존의 todos를 조회하여 concat()을 이용해 새로운 배열은 만들기 때문에 todos에 의존적이라고 할 수 있다. 따라서 todos를 명시해주어야 한다.

두 번째 파라미터에 아무 것도 넣지 않으면??

반면 두 번째 파라미터에 아무 것도 넣지 않을 때도 있다. 그렇게 되면 컴포넌트가 리렌더링 될 때 함수가 재생성 되는 일은 없다.

const onChange = useCallback((e)=>{
  setName(e.target.value);
}, [])

위와 같은 onChange 이벤트 핸들러를 작성했다고 하면 이 경우, 기존 값을 조회하지 않고 바로 설정만 하기 때문에 두 번째 파라미터가 비어있어도 무관하다.

어떠한 값을 조회한다면 그 값을 무조건 두 번째 파라미터에 명시하자

이건 꼭 알고가자!😁

하위컴포넌트에 props값으로 콜백 함수를 넘길 때, 상위 컴포넌트에서 useCallback을 사용하여 선언한 콜백 함수를 props로 넘기는 것이 유용하다.

함수가 다시 선언 될 때 마다 하위 컴포넌트는 props로 받은 콜백 함수가 달라졌다고 인식하기 때문이다.

profile
유능한 프론트엔드 개발자가 되고픈 사람😀

0개의 댓글