[React] - 메모이제이션 훅: useCallback, useMemo

씨즈·2020년 10월 30일
0

react

목록 보기
10/12

useCallback과 useMemo는 이전 값을 기억해서 성능을 최적화하는 용도로 사용된다.

useCallback

useCallback은 리액트의 렌더링 성능을 위해 제공되는 훅이다.
컴포넌트가 렌더링될 때마다 새로운 함수를 생성해서 자식 컴포넌트의 속성값으로 입력하는 경우가 많다. 이것은 부모 컴포넌트가 렌더링될 때마다 자식 컴포넌트의 속성값으로 새로운 함수가 입력되기 때문에 불필요한 렌더링이 발생한다는 문제점이 있다.
리액트에서는 이 문제를 해결하기 위해 useCallback 훅을 제공한다.

>사용법

  • onSave 속성값으로 전달했던 것과 같은 함수를 useCallback 훅의 첫번째 매개변수로 입력한다.
  • useCallback 훅의 두 번째 매개변수는 의존성 배열이고 의존성 배열이 변경되지 않으면 이전에 생성한 함수가 재사용된다.
  • 따라서 name과 age 값이 변경되지 않으면, UserEdit 컴포넌트의 onSave 속성값으로 항상 같은 함수가 전달된다.
import React, { useState, useCallback } from "react";

export default function App() {
  const [name, setName] = useState("");
  const [age, setAge] = useState(0);
  const [v1, setV1] = useState(0);
  const onSave = useCallback(() => saveToServer(name, age), [name, age]);
  // 자식 컴포넌트에게 속성으로 내려줄 함수를 useCallback 훅의 첫 번째 매개변수로 입력하고 두 번째 매개변수로 의존성 배열을 넣어준다. 
  // 의존성 배열이 변경되지 않으면 이전에 생성한 함수가 재사용된다. 따라서 name과 age값이 변경되지 않으면 UserEdit 컴포넌트의 onSave 속성값으로 항상 같은 함수가 전달된다. 
  return (
    <div>
      <p>{`name is ${name}`}</p>
      <p>{`age is ${age}`}</p>
      <UserEdit onSave={onSave} setName={setName} setAge={setAge} />
      <UserEdit2
        onSave={() => saveToServer(name, age)}
        setName={setName}
        setAge={setAge}
      />
      // 기존에 이런식 함수를 속성값으로 내려줬을 것이다. 이렇게 되면 부모컴포넌트가 렌더링될 때마다 새로운 함수가 입력되기 때문에 속성값은 항상 변경되고 불필요한 렌더링이 발생한다. 
      <p>{`v1: ${v1}`}</p>
      <button onClick={() => setV1(Math.random())}>v1 수정</button>
    </div>
  );
}

const UserEdit = React.memo(function ({ onSave, setName, setAge }) {
  console.log("UserEdit render");
  return null;
});

const UserEdit2 = React.memo(function ({ onSave, setName, setAge }) {
  console.log("UserEdit2 render");
  return null;
});

function saveToServer(name, age) {}

useMemo

useMemo 훅은 계산량이 많은 함수의 반환값을 재활용하는 용도로 사용된다.

>사용법

  • useMemo 훅의 첫 번째 매개변수로 함수를 입력한다. useMemo 훅은 이 함수가 반환한 값을 기억한다.
  • 두 번째 매개변수는 의존성 배열이다. 의존성 배열이 변경되지 않으면 이전에 반환된 값을 재사용한다.
  • 만약 배열의 값이 변경됐으면 첫 번째 매개변수로 입력된 함수를 실행하고 그 반환값을 기억한다.
import React, { useMemo, useState } from "react";

export default function App() {
  const [v1, setV1] = useState(0);
  const [v2, setV2] = useState(0);
  const [v3, setV3] = useState(0);
  const value = useMemo(() => runExpensiveJob(v1, v2), [v1, v2]);
  return (
    <>
      <p>{`value is ${value}`}</p>
      <button
        onClick={() => {
          setV1(Math.random());
          setV2(Math.random());
        }}
      >
        v1/v2 수정
      </button>
      <p>{`v3 is ${v3}`}</p>
      <button onClick={() => setV3(Math.random())}>v3 수정</button>
    </>
  );
}

function runExpensiveJob(v1, v2) {
  console.log("runExpensiveJob is called");
  // run something too expensive
  // 계산이 많고 복잡한 로직이 있다고 가정한다. 
  return v1 + v2;
}
profile
Seize the day

0개의 댓글