Contents
see List작성일 2025. 11. 30.
React 18 Concurrent Features
React 18에서 도입된 Concurrent Rendering은 React가 여러 버전의 UI를 동시에 준비할 수 있게 해주는 핵심 기능입니다. 사용자 경험을 크게 향상시키는 새로운 훅과 API를 제공합니다.
언제 사용하나요?
- 대규모 리스트 렌더링 시 입력 지연 방지
- 페이지 전환 시 이전 페이지를 유지하며 로딩
- 검색 자동완성 등 빈번한 상태 업데이트
- 사용자 인터랙션 우선순위 관리
React 18 업그레이드
// React 18 설치
npm install react@18 react-dom@18
// index.js 변경
import { createRoot } from "react-dom/client";
const container = document.getElementById("root");
const root = createRoot(container);
root.render(<App />);useTransition - 우선순위 낮추기
import { useState, useTransition } from "react";
function SearchPage() {
const [query, setQuery] = useState("");
const [results, setResults] = useState([]);
const [isPending, startTransition] = useTransition();
const handleChange = (e) => {
// 긴급: 입력값 즉시 업데이트
setQuery(e.target.value);
// 낮은 우선순위: 검색 결과 업데이트
startTransition(() => {
setResults(searchItems(e.target.value));
});
};
return (
<div>
<input value={query} onChange={handleChange} />
{isPending ? (
<div>검색 중...</div>
) : (
<ResultList results={results} />
)}
</div>
);
}useDeferredValue - 값 지연
import { useDeferredValue, useMemo } from "react";
function ProductList({ searchQuery }) {
// searchQuery의 지연된 버전
const deferredQuery = useDeferredValue(searchQuery);
// 실제 필터링은 지연된 값으로
const filteredProducts = useMemo(
() => products.filter(p =>
p.name.includes(deferredQuery)
),
[deferredQuery]
);
// 지연 중일 때 시각적 피드백
const isStale = searchQuery !== deferredQuery;
return (
<div style={{ opacity: isStale ? 0.5 : 1 }}>
{filteredProducts.map(p => (
<ProductCard key={p.id} product={p} />
))}
</div>
);
}Suspense 향상
import { Suspense, lazy } from "react";
const Comments = lazy(() => import("./Comments"));
const Sidebar = lazy(() => import("./Sidebar"));
function App() {
return (
<div>
<Header />
<Suspense fallback={<Spinner />}>
<main>
<Content />
<Suspense fallback={<CommentSkeleton />}>
<Comments />
</Suspense>
</main>
<Suspense fallback={<SidebarSkeleton />}>
<Sidebar />
</Suspense>
</Suspense>
</div>
);
}Automatic Batching
// React 18에서는 모든 업데이트가 자동 배칭됨
function handleClick() {
// 이전: 각각 리렌더링
// React 18: 한 번만 리렌더링
setCount(c => c + 1);
setFlag(f => !f);
}
// 비동기 함수 안에서도 배칭됨
async function handleSubmit() {
await saveToServer();
setCount(c => c + 1); // 한 번만
setFlag(f => !f); // 리렌더링
}
// 배칭 해제가 필요한 경우
import { flushSync } from "react-dom";
flushSync(() => {
setCount(c => c + 1);
}); // 즉시 리렌더링
flushSync(() => {
setFlag(f => !f);
}); // 다시 리렌더링useId - SSR 안전한 ID 생성
import { useId } from "react";
function FormField({ label }) {
const id = useId();
return (
<div>
<label htmlFor={id}>{label}</label>
<input id={id} />
</div>
);
}
// 여러 ID가 필요한 경우
function ComplexForm() {
const id = useId();
return (
<>
<label htmlFor={id + "-name"}>이름</label>
<input id={id + "-name"} />
<label htmlFor={id + "-email"}>이메일</label>
<input id={id + "-email"} />
</>
);
}주의사항
- Strict Mode에서 컴포넌트가 두 번 렌더링됨
- Concurrent 기능은 createRoot 필수
- 클래스 컴포넌트에서는 일부 기능 제한
- IE 지원 중단됨
javascript
| No | 작성일 | Title |
|---|---|---|
| 2350 | 2026. 04. 07. | ES2025 Iterator Helpers 완벽 가이드 - map, filter, take를 이터레이터에서 직접 사용하기 |
| 2336 | 2026. 04. 06. | ES2025 새 기능 실전 가이드 - Promise.try, Iterator Helpers, Set 메서드 총정리 |
| 2321 | 2026. 04. 05. | ES2026 Temporal API 완벽 가이드: Date 객체를 대체하는 새로운 표준 |
| 2296 | 2026. 04. 05. | Temporal API로 JavaScript 날짜/시간 처리 완전 정복하기 |
| 2295 | 2026. 04. 05. | ES2026 using 키워드와 Explicit Resource Management 완벽 가이드 |
| 2268 | 2026. 04. 04. | Node.js 22 완벽 가이드: 네이티브 TypeScript, WebSocket, Permission Model 실전 활용 |
| 2267 | 2026. 04. 04. | ES2025 새 기능 총정리: Promise.try, Set 메서드, RegExp 플래그까지 |
| 2216 | 2026. 02. 11. | Zustand vs Jotai: 경량 상태관리 라이브러리 비교 |
| 2215 | 2026. 02. 11. | Bun 1.x 런타임과 빌드 도구 실전 가이드 |
| 2214 | 2026. 02. 11. | TypeScript 5.x 신기능과 고급 타입 시스템 |