rerender 시, render 함수만 재호출 하는 클래스 컴포넌트와 다르게, 함수형 컴포넌트는 코드 전체가 재호출 된다.
따라서 함수/변수가 재정의 되는데, 이를 막고자 고안된 hooks다.
const result = React.useMemo(Function, Array)
최초에 1번재 파라미터인 함수의 return값을 변수(result)에 저장
해 놓았다가, 2번째 파라미터인 배열의 원소들의 값이 변하기 전까지 1번째 파라미터 함수를 재수행하지 않는다.
const result = React.useCallback(Function, Array)
최초에 1번재 파라미터인 함수를 변수(result)에 저장
해 놓았다가, 2번째 파라미터 배열의 원소로 선언된 값이 변하기 전까지 1번째 파라미터 함수를 생성하지 않는다.
2번째 파라미터인 배열에는,
순수 함수의 경우에는 최초 한번 생성 후 재사용하면 되기때문에 빈배열값을 넣는다
.
그러나 함수안에서 사용하는 변수가 외부 값(컴포넌트 내의 변수)에 의존하는 경우, 외부값이 변하면 함수 또한 재생성 되어야한다.
그렇지 않으면 예전 값을 계속 기억하고있다. 따라서 반드시 의존하는 변수들의 이름을 배열에 넣는다
.
onInsert
함수는 re-rendering 될 때 마다 정의되지 않는다.
관련된 값이 변경될때만 재정의 된다.
avaerage
변수는 re-rendering 될 때 마다 정의되지 않는다.
관련된 값이 변경될때만 재정의 된다.
/// https://github.com/ginameee/react-playground/blob/master/react-hooks/src/useMemoCallback/Average.js
const Average = () => {
const [list, setList] = useState([]);
const [number, setNumber] = useState('');
const onChange = useCallback(({ target: { value } }) => {
setNumber(value);
}, []);
const onInsert = useCallback(e => {
const nextList = list.concat(parseInt(number));
setList(nextList);
setNumber('')
}, [number, list])
const avg = useMemo(() => getAverage(list), [list])
return (
<div>
<div>
<input type="number" value={number} onChange={onChange}></input>
<button onClick={onInsert}>등록</button>
</div>
<ul>
{
list.map(
(n, idx) => <li key={idx}>{n}</li>
)
}
</ul>
<div>
<b>평균값</b> {avg}
</div>
</div>
);
}