React.memo( )
컴포넌트의 props 가 바뀌지 않았다면, 리렌더링을 방지하여 컴포넌트의 리렌더링 성능 최적화를 해주는 함수
- 즉, useState, useReducer, useContext 와 같이 상태와 관련된 리렌더링과는 무관함!
HOC (Higher Order Component) 이며, 렌더링 결과를 메모이징하여 불필요한 리렌더링을 건너 뛰어, UI 성능을 증가시킬 수 있다.
React.memo(컴포넌트)
위처럼 컴포넌트를 감싸주면 된다.
컴포넌트가 React.memo() 로 래핑 될 때 리액트는 컴포넌트를 렌더링 하고 결과를 메모이징한다.
그리고 다음 렌더링이 일어날 때 props 가 동일하다면 리액트는 메모이징된 내용을 재사용해준다. (리렌더링X)
props 동등 비교
React.memo() 는 props 혹은 props 의 객체를 비교할 때 얕은 비교를 한다.
비교 방식을 수정하고 싶다면 React.memo()의 두번째 매개변수로 비교함수를 만들어 넘겨주면 된다.
React.memo(컴포넌트, [equalFunc(prevProps, nextProps)]);
equalFunc(prevProps, nextProps) 함수는 prevProps 와 nextProps 가 같다면 true를 반환해준다.
React.memo() 를 써줘야 할 때
✨ 같은 props 로 렌더링이 자주 일어나거나 무겁고 비용이 큰 연산이 있는 컴포넌트
반대로 React.memo() 를 사용하지 말아야 할 때는 위의 경우가 아닌 경우이다.
성능 관련 변경이 잘못 적용된다면 오히려 악화될 수 있다.
1. 기술적으로 가능하나 클래스 컴포넌트는 React.memo 로 래핑하는 것은 적절하지 않다고 한다.
2. 렌더링될 때 props 가 자주 변하여 동등 비교를 위해 비교 함수를 자주 수행하는 컴포넌트
함수형 업데이트?
상태 변화 함수에 등록하는 콜백함수의 파라미터에서 최신 상태 변수를 참조할 수 있기에 deps에 상태 변수를 넣지 않아도 되므로 최적화가 가능해진다.
React.memo() 와 콜백함수, useCallback
함수 객체는 일반 객체와 동일한 비교 원칙을 따르므로 함수 객체는 자신에게만 동일하다 (즉 비원시 타입..이란거다)
function sumFactory() {
return (a, b) => a + b;
}
const sum1 = sumFactory();
const sum2 = sumFactory();
console.log(sum1 === sum2); // => false
console.log(sum1 === sum1); // => true
console.log(sum2 === sum2); // => true
부모 컴포넌트가 자식 컴포넌트의 콜백함수를 정의하면 새 함수가 암시적으로 생성될 수 있다.
함수의 동등성 때문에 메모이제이션을 적용할 때는 콜백을 받는 컴포넌트 관리에 주의해야 한다.
리렌더링할 때마다 부모 함수가 다른 콜백 함수의 인스턴스를 넘길 가능성이 있다.
이 문제를 해결하려면 props의 콜백함수를 매번 동일한 콜백 인스턴스로 설정해야하는데, useCallback() 을 사용하여 콜백 인스턴스를 보존시켜준다.
useMemo 와 함께 쓰기
props 가 배열이나 객체 등의 비원시 타입이라면, 부모 컴포넌트가 리렌더링 될 때,
해당 비원시 타입 또한 재정의(선언) 되므로 새로운 메모리 주소를 할당 받고, 결과적으로 값은 변하지 않았지만
메모리 주소를 새로 받았기에 리렌더링이 되어버린다.
이 경우 useMemo 와 함께 사용하면 메모이제이션이 되어 리렌더링을 막을 수 있다.
'Web Study' 카테고리의 다른 글
리액트와 리덕스로 TodoList 만들기 (삭제, 완료, 추가) (0) | 2023.04.09 |
---|---|
리덕스 사용을 위한.. useReducer 개념 (0) | 2023.04.07 |
useContext ? (0) | 2023.04.04 |
벨로퍼트 모던 리액트 정리 1 (0) | 2023.04.03 |
게시판 서비스 시작 - DB 구축 (0) | 2023.03.16 |