반응형
- 모두 리액트에서 ‘메모이제이션’을 담당하는 hook
- **메모이제이션(memoization)**이란 동일한 계산을 반복해야할 때 계산의 결과를 캐싱하고 이를 재사용하도록 하는 기술
- 불필요한 계산을 줄여줌
- 성능향상, 코드 간결성
- useMemo
- 메모이제이션된 값을 반환하는 리액트 hook
- const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
- 첫번째 인자는 값을 연산하고 반환하는 함수, 두번째 인자는 의존성 배열
- 렌더링 시 의존성 배열값의 변경 여부에 따라 실행
- 의존성 배열이 없으면 렌더링할 때마다 매번 실행
- 컴포넌트내에 특정 변수가 변경되었을 때에만 실행되면 되는 코드가 있을 경우 useMemo를 사용하면 불필요한 함수 실행을 줄일 수 있음
- 주의할 점
- 계산에 대한 결과가 메모되어 있으므로 계산에 대한 입력이 변경되지 않으면 업데이트되지 않는다. 즉 계산에 대한 입력이 일정하게 유지되는 경우에만 유용
- 메모된 결과를 확인할 때마다 연산을 수행해야 하므로 잦은 변동이 있을 경우 오히려 성능이 악화될 수 있음
- 메모리 사용
- 남발 시 코드 복잡성
- useCallback
- 메모이제이션된 함수를 반환하는 리액트 hook
- 첫번째 인자는 반환할 함수, 두번째 인자는 의존성 배열
- 사실 렌더링시마다 함수를 선언하는 것은 성능상 큰 영향을 끼치지 않는다. 그렇다면 왜 사용하는가?
- 자바스크립트에서 함수는 객체다. 컴포넌트가 렌더링 될때마다 선언되는 함수는 모두 다른 참조값을 가지므로 다른 객체이다. 이러한 함수를 useEffect의 디펜던시로 사용하면 무한 루프에 빠지게 된다. 이때 이 함수를 useCallback으로 정의하면 재선언되는 것이 아니라 메모리에 저장해둔 함수를 재사용하게 되므로 무한 루프 문제를 해결할 수 있다.
- useMemo와 useCallback을 사용해야 하는 경우
- 연산 혹은 처리량이 매우 많아서 렌더링의 문제가 되는 경우, 리렌더시 비용 절감을 위해서 useMemo를 사용하자
- 함수 자체가 매우 복잡하거나, 다시 계산하는데 비용이 많이 드는 경우에 useCallback을 사용하자.
- 자식 컴포넌트에서 useEffect가 반복적으로 트리거 되거나, 무한 루프에 빠질 위험이 있을 때 useMemo, useCallback을 사용하자
- 자식 컴포넌트에 함수를 props로 넘길 때, 불필요한 렌더링이 일어난다고 판단된다면 useCallback으로 함수 동등성을 유지해주자.
- 사용자의 입력값이 map 혹은 filter 등을 사용하여 이후 렌더링에서도 동일한 참조를 사용할 가능성이 높을 경우 useMemo를 사용해서 메모이제이션을 적용하자
- 리액트 상위 트리에서, 부모가 리렌더링 될 때 자식 컴포넌트까지의 렌더링 전파를 막고 싶을 때 useMemo를 사용하자. 자식 컴포넌트가 useMemo로 메모이제이션 컴포넌트일 경우, 메모이제이션된 props를 사용해 필요한 부분만 리렌더링 할 수 있다.
- ref 함수를 부수작용(side effect)와 함께 전달하거나, ref로 wrapper 함수를 만들 때 useMemo를 사용하자. 리액트는 ref 함수가 변경될 때 마다 과거 값을 null로 호출하고 새로운 함수를 호출하기 때문인데, 이 경우 ref 함수의 이벤트 리스너가 변경되는 등의 불필요한 작업이 일어날 수 있다.
반응형
'개발이야기 > 웹개발' 카테고리의 다른 글
[코드잇 스프린트 풀스택 4기] 리액트 생명 주기(Life Cycle)란 (1) | 2024.12.10 |
---|---|
[코드잇 스프린트 풀스택 4기] 리액트 배열 렌더링 시 key를 지정해야 하는 이유 (0) | 2024.12.10 |
[코드잇 스프린트 풀스택 4기] 리액트(React)의 렌더링 방식 (1) | 2024.11.25 |
[코드잇 스프린트 풀스택 4기] 리액트(React) 컴포넌트 (0) | 2024.11.25 |
[코드잇 스프린트 풀스택 4기] React Virtual DOM (0) | 2024.11.25 |