[React] 컴포넌트 성능 최적화 : 많은 데이터 렌더링

2022. 2. 24. 17:32·공부하기/React

다음 내용은 책 '리액트를 다루는 기술'을 바탕으로 작성된 글입니다.


 

컴포넌트는 다음과 같은 상황에서 리렌더링이 발생한다.

 

1. 자신이 전달받은 props가 변경될 때

2. 자신의 state가 변경될 때

3. 부모 컴포넌트가 리렌더링될 때

4. forceUpdate 함수가 실행될 때

 

리렌더링이 되지 않아도 되는 컴포넌트까지 위의 상황을 만족한다는 이유로 리렌더링이 되다 보면, 성능이 심하게 저하 되는 경우가 발생 된다. 이럴 때는 컴포넌트 리렌더링 성능을 최적화해 주는 작업을 해 주어야 한다.

즉, 리렌더링이 불필요할 때에는 리렌더링을 방지해 주어야 한다.

 

React.memo를 사용하여 컴포넌트 성능 최적화

컴포넌트의 리렌더링을 방지할 때는 shouldComponentUpdate라는 라이프사이클을 사용하면 된다.

그렇지만 함수 컴포넌트에는 라이프사이클 메서드를 사용할 수 없으므로 대신 React.memo 라는 함수를 사용한다.

 

React.memo 함수를 통해 컴포넌트의 props가 바뀌지 않았다면, 리렌더링 하지 않도록 설정할 수 있다.

 

사용법은 컴포넌트를 만들고 나서 export문에서 컴포넌트를 React.memo로 감싸주면 된다.

 

export default React.memo(TodoListItem);

 

 


  const onRemove = useCallback(
    (id) => {
      setTodos(todos.filter((todo) => todo.id !== id));
    },
    [todos],
  );

  const onToggle = useCallback(
    (id) => {
      setTodos(
        todos.map((todo) =>
          todo.id === id ? { ...todo, checked: !todo.checked } : todo,
        ),
      );
    },
    [todos],
  );

 

위의 함수 onRemove와 onToggle은 가장 상단의 부모 컴포넌트의 state인 todos 배열이 업데이트가 될 때마다 함수가 새로 만들어진다.


 이렇게 함수가 계속 만들어지는 상황을 방지하는 방법은 두 가지이다.
첫 번째 방법은, 함수형 업데이트 기능을 사용하는 것
두 번째 방법은 useReducer을 사용하는 것이다.

 


useState의 함수형 업데이트

const [todos, setTodos] = useState([ {....} ,{....},{....} ]);

위와 같이 useState를 이용해 생성된 state를 변경할 때(setTodos), 

새로운 상태를 파라미터로 넣는 대신 상태 업데이트를 어떻게 할지 정의하는 업데이트 함수를 넣는 방법이다.

이를 함수형 업데이트라고 한다.

 

다음은 예시이다.

 

const [number,setNumber] = useState(0);
const onIncrease = useCallback( ()=> {
 setNumber(prevNumber => prevNumber+1),
 [],
);

 

단순히 setNumber(number+1)가 아닌 위의 코드처럼 작성하면 useCallback을 사용할 때 두 번째 파라미터로 넣는 배열에 number를 넣지 않아도 된다.

따라서 number가 변하는 매 순간마다 onIncrease 함수가 불필요하게 재생성되지 않으므로 성능 저하를 막을 수 있다.

 

userReducer 사용

useReducer를 사용하는 방법은 기존 코드를 많이 고쳐야 한다는 단점이 있지만, 상태를 업데이트 하는 로직을 모아서 컴포넌트 바깥에 둘 수 있다는 장점이 있다. 성능상으로는 두 방법이 비슷하기 때문에 어떤 방법을 선택할지는 각자의 취향에 따라 결정하면 된다.

 

 

나는 아직 Reducer의 개념을 공부하지 않아 useReducer를 사용하는 방법은 리덕스를 공부하고 난 뒤 다시 알아볼 생각이다.

 

 

저작자표시 (새창열림)

'공부하기 > React' 카테고리의 다른 글

[React] 중첩된 라우트 , Outlet  (1) 2022.03.01
[React] URL 파라미터와 쿼리스트링  (0) 2022.02.25
[React] 리액트 라우터  (2) 2022.02.25
[React] 컴포넌트 성능 최적화 : 불변성의 중요성  (1) 2022.02.24
[React] useCallback 함수  (1) 2022.02.24
'공부하기/React' 카테고리의 다른 글
  • [React] URL 파라미터와 쿼리스트링
  • [React] 리액트 라우터
  • [React] 컴포넌트 성능 최적화 : 불변성의 중요성
  • [React] useCallback 함수
다섯자두
다섯자두
All I need is 💻 , ☕️ and a dash of luck
  • 다섯자두
    subbni
    다섯자두
  • 전체
    오늘
    어제
    • 전체 글 (88) N
      • 개발 이야기 (0)
      • 만들어보기 (17)
        • FromBookToBook (5)
        • Spring (5)
        • Node.js & React (3)
        • TroubleShooting (4)
      • 공부하기 (71) N
        • Network (3)
        • Cloud (1)
        • Database (5)
        • Java (13)
        • Javascript (0)
        • Spring (9)
        • React (18)
        • Algorithm (8)
        • 자료구조 (7)
        • ETC (7) N
      • 회고 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • velog
  • 공지사항

  • 인기 글

  • 태그

    실시간 데이터 전송 기술
    outbox 패턴
    알고리즘
    Spring
    springboot
    network
    outbox
    Express
    aws
    재시도 로직
    자료구조
    java
    프로젝트
    알림 기능
    최단거리
    SSE
    pdf 자동 다운로드
    pdf 프리뷰 실패
    오블완
    티스토리챌린지
    SQS
    SQL
    서명알고리즘
    redis
    JPA
    Til
    Database
    HTTP
    로그인
    mysql
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
다섯자두
[React] 컴포넌트 성능 최적화 : 많은 데이터 렌더링
상단으로

티스토리툴바