React 18 beta 테스트하며 Concurrent Features 살펴보기
배경
지난 6월 React 18 Working Group이 공개된 후, 이번 주 드디어 beta 버전이 릴리즈되었다. 회사 프로젝트에 바로 적용하긴 어렵지만, 개인 프로젝트에서 테스트해볼 기회가 생겼다.
설치 및 기본 설정
npm install react@beta react-dom@beta
Root API가 변경되어 createRoot를 사용해야 Concurrent Features를 활성화할 수 있다.
import { createRoot } from 'react-dom/client';
const root = createRoot(document.getElementById('root'));
root.render(<App />);
Automatic Batching
가장 눈에 띄는 변화는 모든 업데이트가 자동으로 배치된다는 점이다. 기존에는 이벤트 핸들러 내부에서만 배치가 작동했지만, Promise나 setTimeout 내부에서도 배치가 적용된다.
setTimeout(() => {
setCount(c => c + 1);
setFlag(f => !f);
// React 17: 2번 렌더링
// React 18: 1번 렌더링
}, 1000);
실제로 개발자 도구로 확인해보니 불필요한 리렌더링이 확실히 줄어들었다.
useTransition
검색 필터링이 많은 화면에서 useTransition을 적용해봤다. 입력은 즉시 반영하되, 무거운 필터링 작업은 낮은 우선순위로 처리할 수 있다.
const [isPending, startTransition] = useTransition();
const [query, setQuery] = useState('');
const [filteredList, setFilteredList] = useState(items);
const handleChange = (e) => {
setQuery(e.target.value);
startTransition(() => {
const filtered = items.filter(item =>
item.title.toLowerCase().includes(e.target.value.toLowerCase())
);
setFilteredList(filtered);
});
};
입력 필드는 즉시 반응하고, 리스트 업데이트는 지연되어 사용자 경험이 개선되었다. isPending 플래그로 로딩 상태도 표시할 수 있다.
호환성
기존 React 17 코드는 대부분 그대로 작동했다. ReactDOM.render도 여전히 동작하지만 deprecation 경고가 뜬다. 점진적 마이그레이션이 가능할 것 같다.
Suspense도 개선되었다는데, 아직 서버 사이드에서의 Streaming이 완전히 안정화되지 않아 더 지켜봐야 할 듯하다.
정리
프로덕션 적용은 아직 이르지만, 성능 개선 방향성은 명확해 보인다. 특히 Automatic Batching은 별도 코드 수정 없이도 혜택을 받을 수 있어서 좋았다. 내년 상반기 정식 릴리즈를 기다려봐야겠다.