React 컴파일러
- React 코드를 최적화된 JavaScript로 변환하여 성능을 크게 향상
- 컴포넌트 렌더링을 자동으로 관리하여 수동 상태 및 UI 업데이트가 필요 없어짐
- useMemo, useCallback, memo 등의 수동 최적화 필요성을 줄임
서버 컴포넌트
- 컴포넌트를 서버에서 미리 렌더링하여 초기 페이지 로드 시간을 개선하고 SEO를 향상시킴
- 클라이언트로 전송되는 JavaScript 양을 줄여 성능을 개선
액션(Actions)
- 폼 제출 등의 데이터 변경 작업을 더 쉽게 처리할 수 있게 해줌
- 비동기 작업의 상태 관리를 자동화하여 개발자 경험을 개선
새로운 Hooks
- useOptimistic: 서버 응답 전 UI를 낙관적으로 업데이트함
- useFormStatus: 폼 제출 상태를 관리
- useFormState: 폼 상태를 관리
- use: 렌더링 중 리소스를 읽을 수 있는 새로운 API
로딩 최적화
- 백그라운드에서 이미지와 파일을 미리 로드하여 페이지 전환 시 대기 시간을 줄임
- 새로운 Resource Loading API (preload, preinit)를 제공
문서 메타데이터 지원
- 컴포넌트 내에서 직접 title, meta 태그 등을 렌더링할 수 있게 됨
이전 버전과 기능 비교
Actions와 Form 제출 처리
이전 구현 코드
function ChangeName({ name, setName }) {
const [error, setError] = useState(null);
const [isPending, setIsPending] = useState(false);
const handleSubmit = async (event) => {
event.preventDefault();
setIsPending(true);
try {
const formData = new FormData(event.target);
const newName = formData.get("name");
const error = await updateName(newName);
if (error) {
setError(error);
} else {
setName(newName);
// 리다이렉트 로직
}
} catch (err) {
setError("An unexpected error occurred");
} finally {
setIsPending(false);
}
};
return (
<form onSubmit={handleSubmit}>
<input name="name" defaultValue={name} />
<button type="submit" disabled={isPending}>
{isPending ? "변경 중..." : "변경"}
</button>
{error && <p>{error}</p>}
</form>
);
}
React 19
function ChangeName({ name, setName }) {
const [error, submitAction, isPending] = useActionState(
async (previousState, formData) => {
const error = await updateName(formData.get("name"));
if (error) {
return error;
}
redirect("/path");
}
);
return (
<form action={submitAction}>
<input name="name" defaultValue={name} />
<button type="submit" disabled={isPending}>
변경
</button>
{error && <p>{error}</p>}
</form>
);
}
- React 19의 새로운 Actions 기능과 useActionState Hook을 사용
- useActionState는 폼 제출 로직, 에러 상태, 그리고 로딩 상태를 한 번에 관리
- 첫 번째 인자로 비동기 함수를 받아 폼 제출 로직을 처리
- 반환값으로 [error, submitAction, isPending]을 제공
- action={submitAction}을 통해 폼 제출 시 실행될 액션을 지정
- 이전 버전에서 필요했던 event.preventDefault()나 수동 상태 관리가 필요 없어짐
- 서버 사이드 렌더링과 더 잘 통합, 프로그레시브 인핸스먼트를 지원함
useFormStatus 기능
이전 구현 코드
function SubmitButton({ isPending }) {
return (
<button type="submit" disabled={isPending}>
{isPending ? "제출 중..." : "제출"}
</button>
);
}
function Form() {
const [isPending, setIsPending] = useState(false);
const handleSubmit = async (event) => {
event.preventDefault();
setIsPending(true);
try {
// 폼 제출 로직
} finally {
setIsPending(false);
}
};
return (
<form onSubmit={handleSubmit}>
{/* 폼 필드들 */}
<SubmitButton isPending={isPending} />
</form>
);
}
React 19
import { useFormStatus } from "react-dom";
function SubmitButton() {
const { pending } = useFormStatus();
return (
<button type="submit" disabled={pending}>
{pending ? "제출 중..." : "제출"}
</button>
);
}
function Form() {
const handleSubmit = async (formData) => {
// 폼 제출 로직
};
return (
<form action={handleSubmit}>
{/* 폼 필드들 */}
<SubmitButton />
</form>
);
}
- 새로운 useFormStatus Hook을 사용
- useFormStatus는 현재 폼의 제출 상태를 추적, pending 상태를 통해 폼이 제출 중인지 여부를 알 수 있음
- SubmitButton 컴포넌트는 폼의 상위 컴포넌트와 상태를 공유할 필요 없이 자체적으로 제출 상태를 관리함
- Form 컴포넌트는 action prop에 직접 핸들러 함수를 전달
- 이전 버전에서 필요했던 useState와 isPending 상태 관리가 필요 없어짐
- 코드가 더 선언적이고 간결해짐, 컴포넌트 간 결합도가 낮아짐.
출처:
https://ko.react.dev/blog/2024/04/25/react-19
'TIL' 카테고리의 다른 글
[TanStackQuery] ReactQuery 개념 정리 (1) | 2024.10.20 |
---|---|
[Firebase] Auth, Store 사용하기 (1) | 2024.09.25 |
[AWS TechCamp] AWS 서버리스로 서버 고민 없이 웹 애플리케이션 구축하기 (2) | 2024.09.04 |
[CSS] BEM(Block, Element, Modifier) 모델 (0) | 2024.08.29 |
[독서] 선물받은 「나는 네이버 프런트엔드 개발자입니다」 책 읽기 (0) | 2024.08.23 |