키 입력은 즉시 반응해야 하지만 큰 결과 목록은 조금 늦어도 돼. useTransition으로 긴급한 업데이트와 미뤄도 되는 업데이트를 구분해.
기본 모양
const [isPending, startTransition] = useTransition()을 호출하고, 미뤄도 되는 상태 변경을 startTransition(() => setX(...))로 감싸. React는 그 변경을 낮은 우선순위로 처리하고, isPending은 아직 끝나지 않은 transition이 있는지 알려 줘.
검색 입력과 결과 목록을 분리해
검색창의 글자는 누르는 즉시 바뀌어야 하지만, 새 검색어로 수천 개 항목을 거르는 결과 목록은 조금 뒤따라와도 괜찮아. 입력 상태는 바로 갱신하고 결과 상태만 transition으로 바꾸면 키 입력은 막히지 않고 무거운 목록은 백그라운드에서 새 결과를 준비해.
Suspense와 함께 쓰면 이전 화면을 지킬 수 있어
상태 변경 때문에 자식이 중단되면 보통 Suspense의 대체 UI가 나타날 수 있어. 그 변경을 transition으로 표시하면 React는 새 화면이 준비될 때까지 이전 내용을 유지해. 화면 전체를 빈 로딩 상태로 바꾸는 대신 isPending으로 상단 진행 막대나 옅은 표시를 보여 줄 수 있어.
비동기 작업 자체를 감싸지는 마
startTransition 안에는 우선순위를 낮출 상태 변경을 넣어. fetch나 타이머 같은 비동기 작업은 밖에서 실행하고, 결과를 상태에 반영하는 부분만 감싸면 돼.
const data = await fetchResults(query);
startTransition(() => setResults(data));
우선순위는 작성자가 알려 줘야 해. React는 어떤 변경이 입력만큼 급한지 스스로 알 수 없어. useTransition은 사용자의 조작을 먼저 지키고, 늦어도 되는 화면 갱신은 뒤로 미루겠다는 의도를 표현해.
입력 자체를 transition으로 늦추지 마
제어되는 input의 value를 바꾸는 상태는 즉시 반영해야 커서와 타이핑이 자연스러워. 검색어 state는 바로 바꾸고 그 값으로 만드는 무거운 결과 state만 startTransition 안에서 갱신해.
Transition 작업은 더 긴급한 입력이 오면 중단됐다가 최신 값으로 다시 시작될 수 있어. 중간 렌더링이 화면에 확정되지 않을 수 있으므로 렌더링 중 부수 효과를 실행하면 안 돼.