React 18 useDeferredValue 심화: 검색 자동완성에서 디바운싱을 제거하는 이유

React 18 useDeferredValue 심화: 검색 자동완성에서 디바운싱을 제거하는 이유

⏳ React 18 useTransition 실전: isPending으로 만드는 쾌적한 로딩 UI

⏳ React 18 useTransition 실전: isPending으로 만드는 쾌적한 로딩 UI

화면이 멈추는 '버벅임' 대신, 부드러운 '전환'을 선물하는 방법


웹 애플리케이션을 개발하다 보면 탭을 클릭하거나 페이지를 이동할 때, 데이터를 불러오느라 화면이 순간적으로 얼어버리는 경험을 하게 됩니다.
기존에는 isLoading 상태를 따로 만들어 거대한 스피너(Loading Spinner)로 화면을 가려버리곤 했죠.
하지만 이는 사용자의 흐름을 끊고, 앱이 느리다는 인상을 줍니다.

🚧 기존 방식의 문제점

"탭을 눌렀는데 내용이 나올 때까지 아무것도 못 하고 기다려야 해요."
"깜빡거리는 로딩 화면이 눈을 피로하게 만들어요."

React 18의 useTransition 훅은 이 문제를 해결하는 가장 우아한 방법입니다.
오늘은 startTransition으로 업데이트의 우선순위를 조절하고, isPending을 활용해 사용성을 해치지 않는 로딩 UI를 구현하는 실전 패턴을 알아보겠습니다.


🧩 1. useTransition의 해부학

useTransition 훅은 두 가지 값을 배열 형태로 반환합니다.
이 두 가지가 짝을 이뤄 '멈추지 않는 화면'을 만들어냅니다.

const [isPending, startTransition] = useTransition();

  • 🔹 isPending (boolean)
    현재 우선순위가 낮은 상태 업데이트가 진행 중인지 알려주는 플래그입니다.
    "지금 데이터를 처리하고 있어요(true)" 혹은 "다 끝났어요(false)"를 나타냅니다.
    이 값을 이용해 로딩 인디케이터를 보여줍니다.
  • 🔹 startTransition (function)
    상태 업데이트 함수를 감싸서 실행하는 함수입니다.
    "이 업데이트는 급하지 않으니, 다른 중요한 일(클릭 등)부터 처리해!"라고 리액트에게 알립니다.

💻 2. 실전 구현: 느린 탭 전환 개선하기

무거운 데이터를 렌더링해야 하는 탭 전환 기능을 예로 들어보겠습니다.
일반적인 setState를 사용하면 탭을 누르는 순간 화면이 멈춥니다.
하지만 useTransition을 적용하면 이전 화면을 유지하면서 백그라운드에서 다음 화면을 준비합니다.

// 탭 컴포넌트 예시

import

{ useState, useTransition }

from

'react';

function

TabContainer() {

const [tab, setTab] = useState('home');

const [isPending, startTransition] = useTransition();


const handleTabChange = (nextTab) => {

// 급하지 않은 업데이트로 표시

startTransition(() => {

setTab(nextTab);

});

};


return (

<div>

<TabButton onClick={() => handleTabChange('posts')} />


{/* isPending 상태를 활용한 UI 처리 */}

<div style={{ opacity: isPending ? 0.5 : 1 }}>

{tab === 'posts' && <HeavyPosts />}

</div>

</div>

);

}

위 코드의 핵심은 style={{ opacity: isPending ? 0.5 : 1 }} 부분입니다.
새로운 탭의 내용이 준비되는 동안, 기존 화면이 사라지지 않고 살짝 흐려지면서(Dimmed) 사용자에게 "로딩 중입니다"라는 신호를 줍니다.
사용자는 여전히 다른 탭을 클릭하거나 이전 내용을 읽을 수 있습니다. 이것이 바로 Non-blocking UI입니다.


🎨 3. isPending을 활용한 UX 디자인 패턴

단순히 스피너를 돌리는 것보다, isPending을 활용하면 훨씬 다양한 UX 패턴을 만들 수 있습니다.
상황에 맞는 피드백 방식을 선택해보세요.

패턴 이름 구현 방법 추천 상황
Receded (물러남) 전체 컨텐츠의 opacity를 낮춤 페이지 이동, 탭 전환
Inline Loader 클릭한 버튼 옆에 작은 스피너 표시 폼 제출, 좋아요 버튼
Skeleton (유지) 이전 데이터를 그대로 보여주며 상단에 진행바(Bar) 표시 검색 결과 필터링

💡 핵심 팁

Suspense는 데이터가 '없을 때' 대체 화면을 보여주는 용도라면,
useTransition은 데이터가 '바뀌는 중'일 때 이전 화면을 유지해주는 용도입니다.
이 둘을 적절히 섞어 쓰는 것이 베스트 프랙티스입니다.


🚀 더 이상 사용자를 기다리게 하지 마세요

React 18의 useTransition은 단순한 성능 최적화 도구가 아닙니다.
이것은 "앱이 멈추지 않고 항상 반응한다"는 신뢰를 사용자에게 주는 UX 도구입니다.

✅ 이번 글의 Action Plan

  • 내 프로젝트에서 클릭 시 약간의 딜레이가 발생하는 버튼을 찾아보세요.
  • 해당 상태 업데이트 로직을 startTransition으로 감싸보세요.
  • isPending을 이용해 클릭한 요소에 투명도(Opacity) 0.7을 적용해 보세요.

댓글 쓰기