Memoization
useMemo와 useCallback을 이해하기 위해서 Memoization의 개념을 먼저 알아야 한다.
Memoization이란 기존에 수행한 연산의 결과값을 어딘가에 저장해두고 동일한 입력이 들어오면 재활용하여 예측되는 반복수행을 제거하고 빠르게 실행하는 기술이다. Memoization을 사용하면 중복연산을 피할 수 있기 때문에 메모리를 조금 사용하여 성능을 최적화 할 수 있다.
useMemo
useMemo는 Memoization된 값을 반환하는 함수이다.
useMemo(() => fn, deps)
useMemo는 deps가 변하면 () => fn라는 함수를 실행하고 그 함수의 반환 값을 반환한다.
deps는 dependency이고, useMemo는 deps에 의존한다.
import React, { useState, useMemo } from 'react';
export default function Calculation({ value }) {
function performCalculation(value) {
console.log('Performing calculation...');
return value * 2;
}
const memoizedResult = useMemo(() => { // useMemo를 사용하여 결과를 Memoization한다.
return performCalculation(value);
}, [value]); // deps에 value를 넣어 value가 변경될 때만 계산을 다시 수행하도록 한다.
return (
<div>
<p>Value: {value}</p>
<p>Result: {memoizedResult}</p>
</div>
);
}
performCalculation 함수는 매 렌더링마다 호출하기 때문에 비효율적이다.
useMemo를 사용하여 performCalculation의 결과를 memoizedResult 변수에 메모이제이션 한다. 이후 value의 값이 바뀌지 않으면 memoization한 값을 보내주고, value 값이 바뀌었다면 계산을 수행하도록 한다.
useMemo는 함수나 계산 결과를 캐싱하여 성능 향상을 이끌어내는 데 사용된다. 함수 또는 연산이 많은 리렌더링에서 변경되지 않는 한 캐시된 결과를 재사용한다.
useCallback
useMemo는 함수를 실행하지만, useCallback은 함수를 반환한다.
useCallback(fn, deps)
useCallback은 deps의 변화가 생기게 되면 새로운 함수를 반환한다.
function ParentComponent() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => { // useCallback 으로 콜백 함수를 메모이제이션 한다.
console.log('클릭!');
setCount(count + 1);
}, [count]); // ccount가 변경될 때만 함수가 재생성됩니다.
return (
<div>
<p>카운트: {count}</p>
<ChildComponent onClick={handleClick} />
</div>
);
}
부모 컴포넌트에서 state를 관리하고 자식 컴포넌트에서 클릭이벤트를 처리하는 콜백함수를 prop으로 전달받는다.
useCallback을 사용하여 handleClick을 메모이제이션 한다. handleClick의 의존성배열에 count를 넣어 count state가 변경될때만 함수가 재생성된다. 이렇게 작성하여 불필요한 함수 생성을 방지하고 메모리를 절약할 수 있다.
자식 컴포넌트에 전달된 handleClick함수가 최신 state 상태를 사용하면서 성능 최적화도 할 수 있다.
두 함수가 비슷한듯 다르지만, React 공식문서를 확인해본 결과 두 식은 같다고 본다.
useCallback에서 deps가 변할때 반환되는 함수는 이전 함수와 같은 형태지만 다른 함수이다. 같은 값을 가지고 있지만 메모리 주소가 다르기 때문에 다른 함수로 봐야한다.
React.memo
React.memo는 함수 컴포넌트를 렌더링 최척화를 하기 위한 고차컴포넌트(Higher Order Component)이다. React.memo를 사용하면 컴포넌트가 동일한 Props로 렌더링될 때, 리렌더링을 방지할 수 있다.
React.memo로 컴포넌트를 감싸 컴포넌트 자체를 메모이제이션하고, 이전 Props와 비교하여 변경 여부를 판단한다. 변경된 Props가 있는 경우에만 리렌더링한다.
export function Component(props) {
return (
<div>{props}<div>
)
}
export const MemoizedComponent = React.memo(Component);
Component의 props의 변동이 없으면 MemoizedComponent에 저장된 값을 그대로 사용한다.
'TIL' 카테고리의 다른 글
[React] API 호출함수 관심사의 분리 (0) | 2023.08.27 |
---|---|
[React] Props와 State, Context API (0) | 2023.08.08 |
[Web] LocalStorage SessionStorage Cookie (0) | 2023.08.06 |
[React] Virtual DOM (0) | 2023.07.27 |
브라우저 렌더링 과정에 대해 알아보자 (0) | 2023.07.26 |