일괄처리(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이 된다.
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);
});
startTransition
은 setTimeout
과 달리 즉시 실행된다.setTimeout
은 보장된 delay가 있는 반면, startTransition
는 디바이스의 속도와 다른 urgent 한 renders에 따라 delay 가 달라진다.setTimeout
과 달리 startTransition
업데이트는 interrupted 될 수 있으며 page를 freeze 시키지 않는다.startTransition
로 지정됐을 경우 React는 pending 상태를 추적할 수 있다.Suspense
를 사용하면 어떤 작업이 끝날 때까지 컴포넌트의 렌더링을 잠시 중단시키고 다른 컴포넌트를 먼저 렌더링할 수 있다. (ex. 네트워크를 통해 비동기로(asynchronously) 데이터를 가져오는 작업)
비동기로 데이터를 읽어오는 것은 항상 필요한 일이지만 React로 직접 구현하기에는 까다로운 면이 있기 때문에 라이브러리나 프레임워크에서 제공하는 data loader에 의존하는 경우가 많다.
Suspense
는 어떤 컴포넌트가 읽어야 하는 데이터가 아직 준비가 되지 않았다고 React에게 알려주는 새로운 매커니즘이다.
이를 위해 server rendering을 사용할 수 있다.
즉, ✅ React 18에서는 Suspense
를 사용하여 하나의 slow 컴포넌트가 전체 앱의 렌더링 속도를 늦추지 않게 할 수 있다.
✅ 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.
useTransition
useDeferredValue
useTransition
hook 와 마찬가지로 concurrency hook 이다. useId
useSyncExternalStore
useTransition
과 useDeferredValue
hook은 앱 코드와 함께 작동하는 반면, useSyncExternalStore
는 라이브러리와 함께 작동한다. useInsertionEffect
useLayoutEffect
hook 에서 레이아웃을 읽기 전에 DOM의 스타일을 지정한다.[참고]