React Version 18

2023. 1. 31. 21:29프로그래밍/React

    목차

Automatic batching

업데이트 대상이 되는 상태값들을 하나의 그룹으로 묶어서
한 번의 리렌더링업데이트가 모두 진행될 수 있게 해주는 것

한 함수 안에서 setState를 여러 번 호출시켜도 리렌더링은 단 한번만 발생함

함수의 끝에서 업데이트가 되며 여러 번 리렌더링 하는 것을 막기 때문에 성능에 좋은 영향을 줌

function handleClick() {
  setCount(c => c + 1); // 리렌더링 X
  setFlag(f => !f); // 리렌더링 X
  // 마지막에 한 번만 리렌더링함 
}

 

batch 처리 해제

import { flushSync } from "react-dom";

function handleClick() {
  flushSync(() => {
    setCount(count + 1);
  ));
  // 리렌더링
  
  flushSync(() => {
    setClicked(true);
  });
  // 리렌더링
}

Suspense on the server

리액트의 서버 사이드 렌더링

  1. 서버에서 전체 앱에 대한 데이터를 가져옴
  2. 서버에서 전체 앱을 HTML으로 렌더링하고 응답으로 보냄
  3. 클라이언트에서 전체 앱에 대한 JS 코드를 로드함
  4. 클라이언트에서 JS 논리를 전체 앱에 대해 서버 생성 HTML에 연결함

 

문제점

다음 단계가 시작되기 전에 각각의 단계가 한 번에 완료되어야 함

앱의 일부가 다른 부분보다 느릴 경우 효율적이지 않음

(먼저 생성된 컴포넌트가 생성중인 다른 컴포넌트를 위해 계속 기다려야 함)

 

Suspense

<Suspense />를 사용해 앱을 더 작은 독립 단위로 나눌 수 있음

사용자가 컨텐츠와 더욱 빠르게 상호작용 할 수 있음

생성이 완료된 컴포넌트는 보여지고, 아직 생성중인 컴포넌트는 fallback에 정의된 컴포넌트를 보여줌

<div>
  <Navbar />
    <Suspense fallback={<Spinner />}>
      <Sidebar />
    </Suspense>
    <Suspense fallback={<Spinner />}>
      <Post />
    </Suspense>
    <Suspense fallback={<Spinner />}>
      <Comment />
    </Suspense>
</div>

Transition

상태 업데이트에 우선순위를 줄 수 있음

startTransition이 적용된 업데이트는 긴급하지 않은 것으로 처리되며

다른 긴급한 업데이트가 필요한 경우 중단됨

 

예시)

검색 창 (Urgent Update)

  • 버튼 클릭, 키보드 입력과 같이 업데이트가 즉시 일어나야 하는 상태 값들을 대상으로 함

결과 창 (Transition Update)

  • 사용자가 상태 값의 변화에 따른 업데이트가 즉시 일어나는 것을 기대하지 않음
import { startTransition } from 'react';

// Urgent
setInputValue(input);

startTransition(() => {
  // Secondary
  setSearchQuery(input);
});

 

Transition이 보류 중일 때

우선순위가 밀려서 업데이트 보류가 일어날 경우

useTransition을 사용해 isPending 값을 가져와서 로딩 컴포넌트 보여주기

import { useTransition } from 'react';

const [isPending, startTransition] = useTransition();

...

{isPending && <Spinner />}

 

startTransition 대신 업데이트 보류하는 방법

  1. State 를 두 개로 나누어 다르게 처리함
  2. debounce 이용
  3. setTimeout 이용

React Version 18로 업그레이드

1. react, react-dom 설치

npm install react react-dom

 

2. ReactDOM.render ==> ReactDOM.createRoot 로 변경

ReactDOM.render(<App />, document.querySelector("#root"));
const root = ReactDOM.createRoot(document.querySelector("#root"));
root.render(<App />);