개요
useTransition
은 UI의 일부를 백그라운드에서 렌더링할 수 있게 해주는 React Hook입니다. 긴 렌더링 작업을 비동기적으로 처리해, 사용자가 입력 등 중요한 상호작용을 부드럽게 경험할 수 있도록 도와줍니다.
const [isPending, startTransition] = useTransition()
Reference
useTransition()
컴포넌트의 최상위에서 useTransition
을 호출하면, 트랜지션 상태와 트랜지션을 시작하는 함수를 얻을 수 있습니다.
import { useTransition } from 'react';
function TabContainer() {
const [isPending, startTransition] = useTransition();
// ...
}
반환값
[isPending, startTransition]
: 트랜지션이 진행 중인지 나타내는 불리언 값과, 트랜지션을 시작하는 함수가 배열로 반환됩니다.
startTransition(action)
startTransition
함수는 state 업데이트를 트랜지션으로 감쌀 수 있게 해줍니다.
function TabContainer() {
const [isPending, startTransition] = useTransition();
const [tab, setTab] = useState('about');
function selectTab(nextTab) {
startTransition(() => {
setTab(nextTab);
});
}
// ...
}
- action: 동기적으로 실행되는 함수. 이 안에서 발생한 state 업데이트는 트랜지션으로 처리됩니다.
- startTransition은 반환값이 없습니다.
사용법
비차단(Non-blocking) 업데이트 처리
import { useState, useTransition } from 'react';
function CheckoutForm() {
const [isPending, startTransition] = useTransition();
const [quantity, setQuantity] = useState(1);
function onSubmit(newQuantity) {
startTransition(async function () {
const savedQuantity = await updateQuantity(newQuantity);
startTransition(() => {
setQuantity(savedQuantity);
});
});
}
// ...
}
- startTransition 안에서 state를 업데이트하면, 해당 업데이트는 비차단적으로 처리되어 UI가 멈추지 않습니다.
- isPending을 활용해 로딩 스피너 등 대기 상태를 표시할 수 있습니다.
주의사항 및 Caveats
- useTransition은 Hook이므로 컴포넌트/커스텀 Hook 내부에서만 사용할 수 있습니다.
- startTransition 안에서만 state 업데이트가 트랜지션으로 처리됩니다. setTimeout 등 비동기 콜백에서는 별도로 startTransition으로 감싸야 합니다.
- 트랜지션 내에서 input 등 컨트롤드 컴포넌트의 state를 업데이트하면 동작이 어색해질 수 있습니다. 입력값은 항상 동기적으로 처리하세요.
- await 이후의 state 업데이트는 별도의 startTransition으로 감싸야 트랜지션으로 처리됩니다.
- 여러 트랜지션이 동시에 발생하면 React가 이를 하나로 묶어 처리할 수 있습니다.
- 트랜지션 내 state 업데이트는 다른 업데이트에 의해 중단될 수 있습니다.
트러블슈팅
input 업데이트가 트랜지션에서 동작하지 않는 경우
- input의 value 등은 항상 동기적으로 업데이트해야 하며, 트랜지션으로 감싸면 입력이 느려질 수 있습니다.
트랜지션 내에서 set 함수가 즉시 실행되지 않는 것처럼 보일 때
- startTransition에 전달한 함수는 즉시 실행되며, 내부의 state 업데이트만 트랜지션으로 처리됩니다.
await 이후의 업데이트가 트랜지션으로 처리되지 않는 경우
- await 이후에는 다시 startTransition으로 감싸야 합니다.
반응형