728x90
반응형
리액트에서 제공하는 API 중 useMemo, useCallback, memo는 리액트에서 발생하는 렌더링을 최소화 하기 위해 최적화 기법으로 사용됩니다.
이 세 가지가 모두 최적화 기법이라는것은 알지만 대부분은 정확히 언제 사용하는지에 대해서는 알아 보도록 하겠습니다.
먼저 컴포넌트는 다음과 같은 상황에서 리렌더링이 발생합니다.
- 전달 받은 props가 변경될 때
- 자신의 state가 변경될 때
- 부모 컴포넌트가 리렌더링될 때
1. React.memo
전달 받은 props의 변경이 아닌 다른 상황(2, 3번)으로 인해 리렌더링이 되는 부분을 방지하는 함수를 말합니다.
- 컴포넌트를 만들고 React.memo()로 감싸주면 끝!
const Item = ({ data, onClick }: { data: { id: string; name: string }; onClick: () => void }) => {
return <div onClick={onClick}>{data.name}</div>;
};
export default React.memo(Item);
- Item 컴포넌트는 data, onClick이 바뀌지 않으면 리렌더링이 발생하지 않습니다.
- 하지만 props의 data, onClick가 업데이트되는 상황이 존재하기 때문에 최적화는 여기서 끝이 아닙니다.
2. useCallback
- useCallback은 함수를 메모이제이션 하기 위한 Hook입니다.
- 첫번째 인수는 함수이고, 두번째 인수는 의존 배열을 전달합니다.
- useCallback을 사용하면 함수가 처음 생성될때 한번 생성되며, 이후에는 동일한 함수 인스턴스를 사용하게 된다.
- props로 함수를 전달하는 경우 해당 함수가 변경되면 하위 컴포넌트가 리렌더링되기 때문에 useCallback으로 넘기면 리렌더링을 방지할 수 있다.
const List = () => {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
setCount(prev => prev + 1);
}, []);
return (
<div>
{[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(item => (
<Item key={item} data={{ id: item, name: `Item ${item}` }} onClick={handleClick} />
))}
</div>
);
};
const Item = ({ data, onClick }: { data: { id: number; name: string }; onClick: () => void }) => {
return <div onClick={onClick}>{data.name}</div>;
};
export default React.memo(Item);
handleClick이 List컴포넌트에서 생성되어 Item컴포넌트에 props로 넘기고 있습니다.
만약 useCallback을 사용하지 않았다면 List가 리렌더링 될때마다 handleClick함수가 재생성됨으로 Item컴포넌트 onClick props가 변경되어 Item컴포넌트가 불필요한 리렌더링이 발생하게 됩니다.
하위 컴포넌트에 props로 함수를 전달하는 경우는 useCallback로 감싸서 내려주면 좋다.
3. useMemo
- useMemo는 값을 메모제이션 합니다.
- 첫번째 인수는 함수이고, 두번째 인수는 의존 배열을 전달합니다.
- 의존 배열의 값이 모두 같으면 함수를 실행하지 않고, 메모된 값을 반환합니다.위 코드에서, p1와 p2가 변경되지 않는 한 computeExpensiveValue 함수는 다시 호출되지 않습니다. 왜냐하면 useMemo는 디펜던시 배열을 기반으로 메모이제이션된 값을 반환하기 때문입니다.
- 복잡한 계산을 수행하거나, 대규모 데이터를 처리하는 경우등 useMemo는 특히 렌더링 비용이 높은 컴포넌트에서 유용합니다.
const memoizedVale = useMemo(() => {
return computeExpensiveValue(p1, p2)
}, [p1, p2]);
기본적으로 렌더링 속도가 빠르기 때문에 모든 컴포넌트를 개발할때 최적화 작업에 대해 스트레스를 받지 않아도 됩니다.
하지만! 리스트와 관련된 컴포넌트를 만들때와 리스트 하위의 아이템 컴포넌트들이 업데이트가 자주 발생한다면 그땐 최적화가 꼭 필요합니다.
반응형
'Web' 카테고리의 다른 글
[Next.js] - Pages Router 기반 SSR (1) | 2024.10.15 |
---|---|
[TS] - 함수 오버로딩(Overloading) (0) | 2024.10.06 |
반응형 디자인을 위한 개발자 TIP (0) | 2024.08.16 |
SOP, CORS 개념 (0) | 2023.03.02 |
[React] Redux(리덕스) Concept (1) | 2022.12.31 |