본문 바로가기

리액트 React/Hooks

리액트 훅스 Hooks 4: useMemo

반응형

메모이제이션된 값을 반환합니다.

메모이제이션이란 간단히 연산의 결과값을 저장해놓고 동일한 입력이 들어오면 그 값을 가져오는 것입니다.

 

곱셈 컴포넌트
import React, {useMemo, useState} from 'react';

const getMultiply = numbers => {
    console.log("calculating");
    if(numbers.length === 0) return 0;
    const sum = numbers.reduce((a,b)=> a*b);
    return sum;
};

const Multiply = () => {
    const [list, setList] = useState([]);
    const [number, setNumber] = useState('');

    const onChange = e => {
        setNumber(e.target.value);
    };

    const onClick = e => {
        const nextList = list.concat(parseInt(number));
        setList(nextList);
        setNumber('');
    }

    return(
        <div>
            <input value={number} onChange={onChange} />
            <button onClick={onClick}>multiply</button>
            <ul>
                {list.map((value, index)=>(
                    <li key={index}>{value}</li>
                ))}
            </ul>
            <div>
                    <b>result:</b> {getMultiply(list)}
            </div>
        </div>
    )
}

export default Multiply;

위에 코드는 입력 된 값들을 곱셈해 나갑니다. 하지만 콘솔을 보면 숫자를 등록할 때 뿐만아니라 인풋필드의 값이 수정될 때도 getMultiply가 호출되는 것을 확인할 수 있습니다. 이처럼 렌더링 될때마다 계산하는 것은 낭비입니다.

 

useMemo
import React, {useMemo, useState} from 'react';

const getMultiply = numbers => {
    console.log("calculating");
    if(numbers.length === 0) return 0;
    const sum = numbers.reduce((a,b)=> a*b);
    return sum;
};

const Multiply = () => {
    const [list, setList] = useState([]);
    const [number, setNumber] = useState('');

    const onChange = e => {
        setNumber(e.target.value);
    };

    const onClick = e => {
        const nextList = list.concat(parseInt(number));
        setList(nextList);
        setNumber('');
    }

    const result = useMemo(() => getMultiply(list), [list]);

    return(
        <div>
            <input value={number} onChange={onChange} />
            <button onClick={onClick}>multiply</button>
            <ul>
                {list.map((value, index)=>(
                    <li key={index}>{value}</li>
                ))}
            </ul>
            <div>
                    <b>result:</b> {result}
            </div>
        </div>
    )
}

export default Multiply;

위와 같이 수정하면 이제 list배열의 내용이 바뀔때만 getMultiply 함수가 호출됩니다.

 

useMemo는 성능 최적화를 위해 사용할 수는 있지만 의미상으로 보장이 있다고 생각하지는 마세요. 가까운 미래에 React에서는, 이전 메모이제이션된 값들의 일부를 “잊어버리고” 다음 렌더링 시에 그것들을 재계산하는 방향을 택할지도 모르겠습니다. 예를 들면, 오프스크린 컴포넌트의 메모리를 해제하는 등이 있을 수 있습니다. useMemo를 사용하지 않고도 동작할 수 있도록 코드를 작성하고 그것을 추가하여 성능을 최적화하세요.

- ko.reactjs.org/docs/hooks-reference.html#usememo

useMemo에 대해선 말이 많습니다. 제일 저평가된 hook이란 말도 있고 최적화를 위해 남용하다가 오히려 메모리가 더 할당된다, 프론트엔드에서 쓸일없다 등등 입니다. 

반응형