DarrenKwonDev 2020. 6. 24. 13:08

정의

 

(https://reactjs.org/docs/hooks-reference.html#usecallback)

 

const memoizedCallback = useCallback(
  () => {
    doSomething(a, b);
  },
  [a, b],
);

 

 

useCallback(fn, [])는 []에 담긴 state가 변화할 때마다 fn을 실행합니다. useEffect와 유사한 면이 있습니다.

deps에 반드시 useCallback 내부에서 사용한 state를 넣어주는 것을 잊지 맙시다.

 

 

 

활용

 

이 useCallback을 언제 활용하느냐.

함수로 인한 렌더링 성능을 최적화하는 용도로 사용됨.

 

useMemo가 함수 내부에서 진행되는 연산을 최적화한다면 useCallback은 컴포넌트 내부에 정의된 이벤트 핸들러들을 필요할 때만 렌더하도록 만들어 최적화할 수 있습니다.

 

컴포넌트가 언제 재 렌더링되는지 생각해보면, state가 바뀔 때 입니다. 그런데 state가 자주 바뀌는 입력창 같은 경우에는 input 태그에서 사용되는 이벤트 함수들이 새로 생성되면 낭비일 것입니다. 이런 상황을 막기 위해 useCallBack을 사용하는 것이 좋습니다.

 

그러니까, 아래와 같은 로그인 폼이 존재한다면 id에 한글자 한글자 칠 때마다 state가 변경될 때마다 컴포넌트 내부의 핸들링 이벤트들도 전부 다시 렌더링됩니다.

 

 

 

일반적으로 재렌더링이 자주되는 곳에서 props로 넘겨주는 이벤트 핸들러 함수들은 useCallback으로 감싸주는 것이 좋습니다. 아래와 같은 코드에서는 onChange 마다 실행하는 handleChangeId 함수를 useCallback으로 감싸야 겠네요.

<Input name="user-id" value={id} required onChange={handleChangeId}></Input>

 

deps에 추가해야 하는 내용은, 해당 함수 내에서 state를 사용하는 것이 있다면 그 state를 추가하는 것입니다.

함수 내부에서 사용하는 state를 deps 배열로 넣어야 합니다.

// 사용하는 state 없으므로 deps에 추가할 것 없음
const handleChangeId = useCallback((e) => {
  setId(e.target.value);
}, []);

// password state를 사용하으며 deps에 추가
const onChangePasswordCheck = useCallback(
  (e) => {
    setpasswordCheck(e.target.value);
    setpasswordError(e.target.value !== password);
  },
  [password]
);