개발의 시작과 끝
2021.03.10 / React - Hooks useCallback 본문
useCallback
useCallback은 useMemo와 상당히 비슷한 함수이다.
주로 렌더링 성능을 최적화해야 하는 상황에서 사용한다.
이 Hook을 사용하면 이벤트 핸들러 함수를 필요할 때만 생성할 수 있다.
useMemo에서 구현한 Average 컴포넌트를 보면, onChange와 onInsert라는 함수를 선언했는데,
이렇게 선언하게 되면 컴포넌트가 리렌더링 될 때마다 이 함수들이 새로 생성된다.
대부분은 이러한 방식이 문제가 되지 않지만, 컴포넌트의 렌더링이 자주 발생하거나,
렌더링해야 할 컴포넌트의 개수가 많아진다면 이 부분을 최적화해주는 것이 좋다.
Average.js
import React, { useState, useMemo, useCallback } from 'react';
const getAverage = numbers => {
console.log('평균값 계산중..');
if (numbers.length === 0) return 0;
const sum = numbers.reduce((a, b) => a + b);
return sum / numbers.length;
};
const Average = () => {
const [list, setList] = useState([]);
const [number, setNumber] = useState('');
const onChange = useCallback(e => {
setNumber(e.target.value);
}, []); // 컴포넌트가 처음 렌더링 될 때만 함수 생성
const onInsert = useCallback(
e => {
const nextList = list.concat(parseInt(number));
setList(nextList);
setNumber('');
},
[number, list]
); // number 혹은 list 가 바뀌었을 때만 함수 생성
const avg = useMemo(() => getAverage(list), [list]);
return (
<div>
<input value={number} onChange={onChange} />
<button onClick={onInsert}>등록</button>
<ul>
{list.map((value, index) => (
<li key={index}>{value}</li>
))}
</ul>
<div>
<b>평균값:</b> {avg}
</div>
</div>
);
};
export default Average;
useCallback의 첫 번째 파라미터에는 생성해주고 싶은 함수를 넣어주고,
두 번 째 파라미터에는 배열을 넣어주면 되는데,
이 배열에는 어떤 값이 바뀌었을 때 함수를 새로 생성해주어야 하는지 명시해주어야 한다.
만약에 onChange 처럼 비어있는 배열을 넣게 되면 컴포넌트가 렌더링 될 때
단 한 번만 함수가 생성되며, onInsert처럼 배열 안에 number와 list를 넣게 되면 input 내용이
바뀌거나 새로운 항목이 추가 될 때마다 함수가 생성된다.
함수 내부에서 기존의 상태 값을 의존해야 할 때는 꼭 두 번 재 파라미터 안에 포함을 시켜주어야 한다.
예를 들어 onChange의 경우 기존의 값을 조회하는 일은 없고 바로 설정만 하므로
배열이 비어있어도 상관없지만 onInsert는 기존의 number와 list를 조회해서 nextList를 생성하기 때문에
배열 안에 number와 list를 꼭 넣어줘야 한다.
useCallback(() => {
console.log('hello world!');
}, [])
useMemo(() => {
const fn = () => {
console.log('hello world!');
};
return fn;
}, [])
위의 두 코드는 완벽히 똑같은 코드이다.
useCallback은 결국 useMemo 에서 함수를 반환하는 상황에서 더 편하게 사용할 수 있는 Hook이다.
숫자, 문자열, 객체처럼 일반 값을 재사용하기 위해서는 useMemo를 사용하는 것이 좋고,
함수를 재사용하기 위해서는 useCallback이 좋다.
참고
'리액트' 카테고리의 다른 글
2021.03.14 / Redux (0) | 2021.03.14 |
---|---|
2021.03.10 / React - Hooks useRef (0) | 2021.03.10 |
2021.03.10 / React - Hooks useMemo (0) | 2021.03.10 |
2021.03.08 / React - Hooks useReducer (0) | 2021.03.08 |
2021.03.07 / React - Hooks useContext (0) | 2021.03.07 |