useMemo, useCallback

이짜젠·2021년 6월 24일
0

rerender 시, render 함수만 재호출 하는 클래스 컴포넌트와 다르게, 함수형 컴포넌트는 코드 전체가 재호출 된다.
따라서 함수/변수가 재정의 되는데, 이를 막고자 고안된 hooks다.


useMemo

const result = React.useMemo(Function, Array)

최초에 1번재 파라미터인 함수의 return값을 변수(result)에 저장해 놓았다가, 2번째 파라미터인 배열의 원소들의 값이 변하기 전까지 1번째 파라미터 함수를 재수행하지 않는다.


useCallback

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>
    );
}
profile
오늘 먹은 음식도 기억이 안납니다. 그래서 모든걸 기록합니다.

0개의 댓글