모던 리액트 Deep Dive 10-2. React 18 에서 추가된 useTransition Hook 에 대해 알아봅시다.😆😆😆

리액트 버전 18에 새로 추가된 훅 중에서 useTransition Hook 에 대해 Deep Dive 해 봅니다.

cover-image

🌌 정의

const [isPending, startTransition] = useTransition();

상태 변화를 일으키는 함수의 우선순위를 낮추며, UI 를 차단하지 않고 상태를 업데이트 할 수 있는 React Hook 입니다.

useTransition은 컴포넌트 최상위 수준에서 호출되어 startTransition을 통해 우선순위가 낮은 상태 업데이트(setState)들을 transition이라고 표시하며, 리액트는 UI 렌더링시 우선순위에 따라 업데이트 할 수 있게 됩니다.

👩🏼‍🚒 사용 예시 및 isPending, startTransition 이해하기

function TabContainer() { const [isPending, startTransition] = useTransition(); const [tab, setTab] = useState('about'); function selectTab(nextTab) { console.log('1'); startTransition(() => { console.log('2'); setTab(nextTab); }); console.log('3'); } // 1, 2, 3 순서대로 찍힘. 리액트에서 해당 Scope 를 즉시 호출하기 때문 // ... }
  1. 일부 상태 업데이트를 transition 으로 표시

  2. useTransition 함수는 두 개의 항목이 있는 배열을 반환합니다.

    • isPending 플래그는 대기 중인 transition 이 있는지 알려줍니다.
    • startTransition 함수는 상태 업데이트를 transition 으로 표시할 수 있게 해주는 함수입니다.
  3. startTransition 함수는 상태 변화를 일으키는 콜백함수를 전달받고 “낮은” 우선 순위로 실행됩니다.

  4. startTransition 함수는 하나 이상의 set 함수를 호출하여 일부 state 를 업데이트 하는 함수입니다.

    • 리액트는 매개변수 없이 scope 를 즉시 호출하며, scope 함수를 호출하는 동안 동기적으로 예약된 모든 state 업데이트를 transition 으로 표시함 (non-blocking)

🚨 주의 사항

  1. useTransition 은 컴포넌트나 커스텀 Hook 내부에서만 호출할 수 있습니다.

  2. 해당 state 의 set- 함수에 엑세스 할 수 있는 경우에만 set- 업데이트를 transition 으로 래핑할 수 있습니다.

  3. startTransition 에 전달하는 함수는 동기식 이어야 합니다.

  4. Transition 으로 표시된 state 업데이트는 다른 state 업데이트에 의해 중단됩니다.

  5. Transition 업데이트는 텍스트 입력을 제어하는 데 사용할 수 없습니다.

🧤 사용하는 목적

여러 개의 탭을 클릭했을 때 각기 다른 탭 컴포넌트가 렌더링되는 책의 좋은 예시 코드를 보고 이해가 잘 되었습니다.

useTransition 은 UI 를 차단하지 않고 상태를 업데이트 합니다. 위의 예시에서는 PostsTab 컴포넌트가 오래 걸리는 상태 업데이트를 수행해서, 해당 업데이트가 완료된 이후에 렌더링이 일어나기 때문에 그 시간만큼 렌더 트리가 블락(Block) 됩니다. 이 때문에 사용자는 아무런 동작을 할 수 없이 그냥 멈춰 있는 화면을 보게 되므로 UX 에 좋지 않은 영향을 주게 됩니다.

import { useState } from 'react'; import TabButton from './TabButton.js'; import AboutTab from './AboutTab.js'; import PostsTab from './PostsTab.js'; import ContactTab from './ContactTab.js'; export default function TabContainer() { const [tab, setTab] = useState('about'); function selectTab(nextTab) { setTab(nextTab); } return ( <> <TabButton isActive={tab === 'about'} onClick={() => selectTab('about')}> About </TabButton> <TabButton isActive={tab === 'posts'} onClick={() => selectTab('posts')}> Posts (slow) </TabButton> <TabButton isActive={tab === 'contact'} onClick={() => selectTab('contact')} > Contact </TabButton> <hr /> {tab === 'about' && <AboutTab />} {tab === 'posts' && <PostsTab />} {tab === 'contact' && <ContactTab />} </> ); }

useTransition은 컴포넌트 최상위 수준에서 호출되어 startTransition을 통해 우선순위가 낮은 상태 업데이트(setState)들을 transition이라고 표시하며, 리액트는 UI 렌더링시 우선순위에 따라 업데이트 할 수 있게 됩니다.

Transition을 사용하면 느린 디바이스에서도 사용자 인터페이스 업데이트의 반응성을 유지할 수 있습니다.

Transition을 사용하면 리렌더링 도중에도 UI가 반응성을 유지합니다. 예를 들어 사용자가 탭을 클릭했다가 마음이 바뀌어 다른 탭을 클릭하면 첫 번째 리렌더링이 완료될 때까지 기다릴 필요 없이 다른 탭을 클릭할 수 있습니다.

[클릭!] 도서 구매 링크 🧚🏻

이전 블로그로