[React] React 18에서 업데이트 된 기능

김재훈·2023년 4월 14일
0

자동 배치(Automatic Batching)

배칭은 React가 더 나은 성능을 위해 여러 개의 상태 업데이트를 한 번의 리렌더링(re-render)으로 묶는 작업이다.

예를 들어, 하나의 클릭 이벤트 안에 두 개의 sate 업데이트를 가지고 있다면, React는 언제나 이 작업을 배칭하여 하나의 리렌더링(re-render)으로 만들었다. 아래 코드를 실행해보면 매번 누를 때마다 state를 두 번 변경하지만, React가 한 번의 렌더링만 수행한다.

function App() {
  const [count, setCount] = useState(0);
  const [flag, setFlag] = useState(false);
  
  function handleClick() {
    setCount(c => c + 1);
    setFlag(f => !f);
    // React는 이 함수가 끝나면 리렌더링을 한다 (배칭)
  }
  
  return (
    <div>
      <button onClick={handleClick}>Next</button>
      <h1>{count}</h1>
    </div>
  );
}

React 18 이전까지, React 이벤트 핸들러 내부에서 발생하는 업데이트만 배칭을 하였다. Promise, setTimeout, native 이벤트 핸들러, 그리고 모든 이벤트 내부에서 발생하는 업데이트들은 React에서 배칭되지 않았다.

React 18의 createRoot를 통해 모든 업데이트들은 어디서 왔는가와 무관하게 자동으로 배칭되게 된다.

디폴트로 자동 배치를 지원하며 만일 자동 배칭을 비활성화 하려면 flushSync를 사용하면 된다.

import {flushSync} from 'react-dom';

function handleClick() {
  flushSync(() => {
    setCounter(c => c + 1);
  });
  // DOM 업데이트 완료
  
  flushSync(() => {
    setFlag(f => !f);
  });
  // DOM 업데이트 완료
}

Transitions

Transition은 긴급한 업데이트와 긴급하지 않은 전환 업데이트를 구분하는 개념이다. UI상에 렌더링할 업데이트 우선순위를 정해주는 것이라고 볼 수 있다.

긴급한 업데이트(urgent updates)는 입력, 클릭, 누르기 같은 직관적인 상호작용을 반영한다.
전환 업데이트(transition updates)는 하나의 뷰에서 다른 뷰로의 UI 전환을 의미한다.

긴급 업데이트는 사용자의 입력에 따라 즉각적으로 업데이트 되지 않으면 문제(화면 멈춤, 렉)가 있다고 느끼는 영역이다. 반면에 전환 업데이트는 화면에 즉시 나타나는 걸 기대하지 않는 영역이다.

startTransition를 사용해서 긴급한 업데이트와 전환 업데이트를 구분할 수 있다. startTransition 안에서 정의되면 긴급하지 않은 전환 업데이트로 간주되고, 다른 긴급한 업데이트가 발생하면 중단될 수 있다. 만약 중단된 렌더링이 다른 긴급한 상태 변화로 인해 쓸모없어지면 React는 해당 렌더링 작업을 버리고 최신의 업데이트만 렌더링한다.

import {startTransition} from 'react';

// 긴급한 업데이트
setInputValue(input);

// startTransition 안에서 정의하면 전환 업데이트로 간주한다.
// 긴급한 업데이트가 들어오면 중단된다.
startTransition(() => {
  setSearchQuery(input);
});

Suspense

Suspense는 아직 렌더링이 준비되지 않은 컴포넌트가 있을 때 로딩 화면을 보여주고 로딩이 완료되면 해당 컴포넌트를 보여주는 기능이다.

기본적으로 React는 JSX 코드 안에 들어있는 모든 컴포넌트를 즉시 호출하여 바로 렌더링을 진행한다.

예를 들어 React는 다음과 같이 <UserList/> 컴포넌트가 포함된 JSX 코드를 렌더링할 때 UseList 함수를 바로 호출한다.

<UserList />

하지만 컴포넌트를 아래와 같이 Suspense로 감싸주면 컴포넌트의 렌더링을 특정 작업 이후로 미루고, 그 작업이 끝날 때 까지는 fallback 속성으로 넘긴 컴포넌트를 대신 보여줄 수 있다.

<Suspense fallback={<Spinner />}>
  <UserList />
</Suspense>

참고

profile
김재훈

0개의 댓글