React v18 무엇이 달라졌을까?

김지원·2023년 3월 29일
0

Frontend

목록 보기
20/27

✨ React 18에서 업데이트 된 기능

1. Automatic Batching

일괄처리(batching)setState 함수를 호출하여 일어나는 state(상태)의 변화에 따른 리렌더링 횟수를 줄이는데 도음울 준다.

이전에는 이벤트 핸들러(event handlers) 내에서만 batching을 수행했다.
즉, 이벤트 핸들러 밖에서 일어나는 state update의 경우, batching이 되지 않았다.

예를 들어, 아래처럼 promise의 .then 콜백 내부, setTimeout에서는 batching이 되지 않았다.

fetch('/network').then( () => {
setCounter(); //re-rendered 1 times
setActive();  //re-rendered 2 times
setValue();   //re-rendered 3 times
});

//Total 3 re-renders

React 18에서는 automatic batching으로 인해 promise 내부, setTimeouts, 이벤트 콜백(event callbacks) 에서도 bacthing이 된다.

2. Transitions

non-urgent한 UI 업데이트transition이라고 부른다.

React 18에서는 transition을 사용함으로써 React는 어떤 업데이트를 우선시할지 알 수 있다. 이를 통해 렌더링을 최적화하고, 오래된 렌더링(stale rendering)을 제거하는 것이 쉬워진다.

아래처럼 startTransition을 사용하여 non-urgent한 업데이트를 지정할 수 있다.

import { startTransition } from 'react';

// Urgent: Show what was typed
setInputValue(input);

// Mark any non-urgent state updates inside as transitions
startTransition(() => {
  // Transition: Show the results
  setSearchQuery(input);
});

🤔 transition vs debouncing, setTimeout

  1. startTransitionsetTimeout과 달리 즉시 실행된다.
  2. setTimeout은 보장된 delay가 있는 반면, startTransition는 디바이스의 속도와 다른 urgent 한 renders에 따라 delay 가 달라진다.
  3. setTimeout과 달리 startTransition 업데이트는 interrupted 될 수 있으며 page를 freeze 시키지 않는다.
  4. startTransition로 지정됐을 경우 React는 pending 상태를 추적할 수 있다.

3. Suspense on the server

  1. Code splitting on the server with suspense
  2. Streaming rendering on the server

Suspense를 사용하면 어떤 작업이 끝날 때까지 컴포넌트의 렌더링을 잠시 중단시키고 다른 컴포넌트를 먼저 렌더링할 수 있다. (ex. 네트워크를 통해 비동기로(asynchronously) 데이터를 가져오는 작업)

비동기로 데이터를 읽어오는 것은 항상 필요한 일이지만 React로 직접 구현하기에는 까다로운 면이 있기 때문에 라이브러리나 프레임워크에서 제공하는 data loader에 의존하는 경우가 많다.

Suspense는 어떤 컴포넌트가 읽어야 하는 데이터가 아직 준비가 되지 않았다고 React에게 알려주는 새로운 매커니즘이다.

🤔 Client rendering vs Server rendering

  1. Client rendering
    • 페이지를 실행하는 데 필요한 모든 JS와 함께 서버에서 페이지의 HTML를 로드하고 interactive으로 만든다.
    • 하지만 JS 번들이 크거나 연결 속도가 느린 경우 이 프로세스는 시간이 오래 걸릴 수 있다.
    • 즉, 사용자는 페이지가 interactive 되기까지 오랜 시간을 기다려야 한다.

이를 위해 server rendering을 사용할 수 있다.

  1. Server rendering
    • React 구성 요소의 HTML output을 서버에서 렌더링하고, 서버에서 HTML을 보내는 기술이다.
    • 이렇게 하면 JS 번들이 로드되는 동안, 또 앱이 interactive하게 되기 전에 일부 UI를 볼 수 있다.

즉, ✅ React 18에서는 Suspense를 사용하여 하나의 slow 컴포넌트가 전체 앱의 렌더링 속도를 늦추지 않게 할 수 있다.

4. Strict mode

React 18의 Strict 모드컴포넌트를 이전 상태로 mount, unmount, re-mount하는 것을 시뮬레이션 한다.

이는 React가 미래에 재사용 가능한 상태의 토대를 설정하기 위해 unmount 전 동일한 컴포넌트 상태를 사용하여 tree를 다시 mount하여 이전 화면을 즉시 mount할 수 있도록 한다.

Strict mode will ensure components are resilient to effects being mounted and unmounted multiple times.

✨ React18에서 추가된 hook들

📌 useTransition

  • 일부 상태 업데이트를 non-urgent으로 지정하여 하나의 상태 업데이트를 다른 컴포넌트보다 우선시할 수 있다.

📌 useDeferredValue

  • non-urgent 상태 업데이트의 리렌더링(re-rendering)을 연기시킬 수 있다. useTransition hook 와 마찬가지로 concurrency hook 이다.
  • 이 hook를 사용하면 state transition이 일어나는 동안 원래 값을 유지할 수 있다.

📌 useId

  • 고유 id가 필요한 상황에서 사용한다. (list의 key 제외)
  • 주요 목적은 클라이언트와 서버에서 고유하게 유지되는 ID를 생성하여 React 서버 hydration mismatch 에러를 방지하는 것이다.

📌 useSyncExternalStore

  • useTransitionuseDeferredValue hook은 앱 코드와 함께 작동하는 반면, useSyncExternalStore는 라이브러리와 함께 작동한다.
  • React 앱이 외부 라이브러리를 subscribe하고 데이터를 읽을 수 있게 해준다.

📌 useInsertionEffect

  • 라이브러리와 함께 작동하는 hook이다. 그 중에서도 CSS-in-JS 라이브러리에서 작동한다.
  • 스타일 렌더링 성능 문제를 해결한다.
  • useLayoutEffect hook 에서 레이아웃을 읽기 전에 DOM의 스타일을 지정한다.

[참고]

profile
Make your lives Extraordinary!

0개의 댓글