React 19에서는 사용자 경험을 향상시키기 위해 Actions
, useTransition
, useOptimistic
과 같은 새로운 기능들이 도입되었다. 특히 비동기 처리를 다룰 때, 이 훅들은 기존의 상태 관리 방식보다 더 나은 사용자 인터페이스를 구축할 수 있도록 돕는다. 이번 글에서는 이 새로운 훅들의 차이점과 각각을 가장 효과적으로 사용할 수 있는 예제를 중심으로 설명한다.
기존의 상태 관리 훅 vs React 19의 새로운 훅
기존 훅들: useState
, useEffect
, useReducer
기존의 React 훅은 동기적인 상태 관리를 중심으로 작동한다. 예를 들어, 버튼을 클릭하면 setState
를 통해 바로 상태가 업데이트되고 렌더링이 발생한다. 비동기 처리는 useEffect
나 useCallback
등으로 직접 제어해야 했기 때문에 사용자 경험 측면에서 불편함이 있었다.
useTransition
: 느린 상태 업데이트를 비동기적으로 처리하기
useTransition
은 사용자 인터페이스가 즉각 반응해야 하는 작업과 느려도 괜찮은 작업을 분리할 수 있도록 돕는 훅이다. startTransition
안에 감싼 상태 업데이트는 낮은 우선순위를 가지며, React는 이 업데이트를 가능한 한 나중에 처리한다. 이로 인해 UI는 빠르게 반응하면서도 느린 연산도 무리 없이 처리할 수 있다.
검색 기능에서 결과 필터링하기
jsx
복사편집
import { useState, useTransition } from 'react';
function Search() {
const [query, setQuery] = useState('');
const [results, setResults] = useState([]);
const [isPending, startTransition] = useTransition();
function handleChange(e) {
const value = e.target.value;
setQuery(value);
startTransition(() => {
// 예시용 필터링 로직
const filtered = largeDataSet.filter(item =>
item.toLowerCase().includes(value.toLowerCase())
);
setResults(filtered);
});
}
return (
<div>
<input type="text" value={query} onChange={handleChange} />
{isPending && <p>Loading...</p>}
<ul>
{results.map(result => (
<li key={result}>{result}</li>
))}
</ul>
</div>
);
}
이 예제에서는 입력값이 바뀔 때마다 즉시 입력 필드를 업데이트하고, 결과 필터링은 우선순위를 낮춰 UI 반응성을 확보했다.
useOptimistic
: 낙관적 UI 업데이트
useOptimistic
은 사용자 인터랙션 직후에 서버 응답을 기다리지 않고, 예상되는 결과를 먼저 보여주는 방식이다. 이를 통해 대기 시간 없이 부드러운 UX를 제공할 수 있다. 나중에 실제 응답이 오면 상태를 조정할 수 있다.
댓글 추가하기
import { useState, useOptimistic } from 'react';
function CommentList({ initialComments }) {
const [comments, setComments] = useState(initialComments);
const [optimisticComments, addOptimisticComment] = useOptimistic(
comments,
(state, newComment) => [...state, { id: 'temp', ...newComment }]
);
async function handleSubmit(text) {
addOptimisticComment({ text });
const savedComment = await postCommentToServer(text);
setComments(prev => [...prev, savedComment]);
}
return (
<div>
<ul>
{optimisticComments.map((comment, idx) => (
<li key={idx}>{comment.text}</li>
))}
</ul>
<button onClick={() => handleSubmit('좋은 글이네요')}>댓글 달기</button>
</div>
);
}
여기서 useOptimistic
은 댓글이 실제로 서버에 저장되기 전에 화면에 먼저 표시한다. 사용자 입장에서 기다림 없는 인터랙션을 경험할 수 있다.
차이점 요약
훅 | 주요 기능 | 사용 시점 | 특징 |
---|---|---|---|
useState | 동기 상태 업데이트 | 모든 컴포넌트 내 상태 관리에 사용 | 즉시 렌더링 발생 |
useTransition | 낮은 우선순위 상태 업데이트 처리 | 느린 작업 (예: 필터링, 목록 정렬) | UI 반응성 향상, 병렬적 처리 가능 |
useOptimistic | 낙관적 UI 업데이트 | 서버 응답이 느릴 때 예상 결과 미리 표시 | 사용자 경험 개선, 이후 동기화 처리 필요 |
결론
React 19의 useTransition
과 useOptimistic
은 사용자 경험을 부드럽게 만들기 위한 핵심 도구다. useTransition
은 UI의 반응성을 해치지 않으면서 무거운 상태 업데이트를 처리할 수 있도록 해주고, useOptimistic
은 즉각적인 피드백이 필요한 상황에서 대기 시간을 줄여준다. 이 훅들을 잘 조합하면 더 빠르고 직관적인 리액트 애플리케이션을 만들 수 있다.
TI Tech Lab 이유진 연구원
Source
- https://aurorascharff.no/posts/building-reusable-components-with-react19-actions/https://react.dev/reference/react/useTransition#starttransition
- https://react.dev/reference/react/useTransition#starttransition
Add comment