*useMemouseCallback은 이전 값을 기억해서 성능을 최적화하는 용도로 사용된다.*

useMemo

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

import React, {useMemo} from 'react';
import { runExpensiveJob } from './util';

function MyComponent({v1, v2}) {
  const value = useMemo(() => runExpensiveJob(v1,v2), [v1, v2]);
  return <p>{`value is ${value}`}</p>;
}

useCallback

useCallback 은 리액트의 렌더링 성능을 위해 제공되는 훅이다. 컴포넌트가 렌더링 될 때마다 새로운 함수를 생성해서 자식 컴포넌트의 속성값(prop) 으로 입력하는 경우가 많다.

import React, {useSatate} from 'react';
import {saveToServer} from './api';
import UserEdit from './UserEdit';

function Profile(){
  const [name, setName] = useState('');
  const [age, setAge] = useState(0);
  
  return (
    <div>
      <p>{`name is ${name}`}</p>
      <p>{`age is ${age}`}</p>
      <UserEdit 
        onSave={() => saveToServer(name, age)}
        setName={setName}
        setAge={setAge}
      />
    </div>
  );
}

*Profile 컴포넌트가 렌더링될 때마다 UserEdit 컴포넌트의 onSave prop으로 새로운 함수가 선언된다. 따라서 UserEdit 컴포넌트에서 React.memo를 사용해도 onSave prop이 항상 변경되고 그 때문에 불필요한 렌더링이 발생한다.*

*useCallback 훅을 사용하면 불필요한 렌더링을 막을 수 있다.*

function Profile(){
  const [name, setName] = useState('');
  const [age, setAge] = useState(0);
  const onSave = useCallback(() => saveToServer(name, age), [name, age]);
  return (
    <div>
    	<p>{`name is ${name}`}</p>
    	<p>{`age is ${age}`}</p>
			<UserEdit onSave={onSave} setName={setName} setAge={setAge} />
    </div>
  );
}

이전에 onSave 속성값으로 전달했던 것과 같은 함수를 useCallback 훅의 첫 번째 매개변수로 입력한다. useCallback 훅의 두 번째 매개변수는 의존성(dependency) 배열이다. 의존성 배열이 변경되지 않으면 이전에 생성한 함수가 재사용된다. 따라서 nameage 가 변경되지 않으면, UserEdit 컴포넌트의 onSave prop으로 항상 같은 함수가 전달된다.

( state의 함수(setName, setAge)는 useCallback 없이도 같은 주소의 함수로 취급된다. )

React.memo