06.26.2023
1. 메모이제이션의 정의
같은 함수가 같은 값을 계속 리턴해야할 때, 첫 번째 값을 메모리에 저장해놓고 메모리에서 값을 불러와 재사용하는 메모리 사용 기법.
2. 활용도
2-1. useMemo
예를 들어 이러한 함수형 컴포넌트가 있다고 하자.
function Component () {
const result = calculate();
return <div> {result} </div>
}
function calculate () {
// 무거운 작업을 하는 코드
return 10;
}
이 컴포넌트가 렌더링이 될 때마다 calculate은 무거운 작업을 계속해야 할 것이다. 그러나 result는 항상 10일 때, 성능이 비효율적이 될 것. 이럴 때 메모이제이션을 사용하여 해결 가능
function Component () {
const result = useMemo(
() => calculate(), []
);
return <div> {result} </div>
}
function calculate () {
// 무거운 작업을 하는 코드
return 10;
}
React hook인 useMemo를 쓰면 반복적으로 컴포넌트가 불려와도 calculate 함수는 딱 한 번만 실행되며, 그 이후로는 메모리에 저장된 result값을 불러와 화면에 띄운다.
Warning. useMemo는 만병통치약이 아니다.
당연하게도 useMemo가 모든 것을 해결해줄 수는 없다. 메모리를 불필요한 값으로 채워버리면 성능이 내려가게 될 것이 자명하기 때문에 useMemo는 필요할 때만 쓰는 것으로 하자.
2-2. useCallback
useCallback도 useMemo와 비슷한 목적으로 쓰인다. useMemo는 리턴값을 메모이제이션 해준다면, useCallback은 함수 자체를 메모이제이션 할 때 쓰인다.
예시
function Component() {
const [number, setNumber] = useState(0);
const someFunction = () => {
console.log(`number: ${number}`);
return;
};
useEffect(()=>{
console.log('someFunction has been changed');
}, [someFunction]);
return (
<input value={number} type="number" onChange={(e) => setNumber(e.target.value)} />
<button onClick={someFunction}>Call someFunction</button>
}
이 코드의 의도는 input value가 바뀔 때는 useEffect안의 코드가 실행되지 않고, 버튼을 눌렀을 때(someFunction이 바뀌었을 때)만 실행되도록 하는 것이다. 그러나 실제로는 input value가 바뀔 때마다 useEffect 안의 코드가 실행될 것이다. 왜 그럴까?
someFunction은 객체이다. 자바스크립트에서 원시값은 값 그대로 변수에 저장되지만, 객체는 메모리주소의 형태로 변수에 저장된다. 함수도 객체에 해당되므로, someFunction은 렌더링이 될 때마다 재할당되며 메모리주소가 변경되고 결국엔 "다른" 값이 되어 렌더링 될 때마다 useEffect가 실행되는 것이다. 이것을 해결할 수 있느 방법은 useCallback이다.
function Component() {
const [number, setNumber] = useState(0);
const someFunction = useCallback(() => {
console.log(`number: ${number}`);
return;
}, [number]);
useEffect(()=>{
console.log('someFunction has been changed');
}, [someFunction]);
return (
<input value={number} type="number" onChange={(e) => setNumber(e.target.value)} />
<button onClick={someFunction}>Call someFunction</button>
}
3. 결론
메모이제이션은 리액트에서 매우 중요한 컨셉이다. 특히 렌더링 최적화에서 핵심 개념이 되니 꼭 잘 알고 넘어가자.
'Project > Time Map' 카테고리의 다른 글
[문제 해결] 리액트에서 최신 상태 보장 방법 (0) | 2023.09.24 |
---|---|
[React] Modal을 재사용 가능한 컴포넌트로 리팩토링하기 (0) | 2023.08.30 |