Back to blog
May 20, 2024
4 min read

React19 beta와 그 외 변경점

React 19 beta 변경점

React 19가 beta로 출시되었습니다. 정식 버전이 출시 되기 전, 간단하게 정리해봅니다.

1. Action

useTransition

기존에 비동기 상태 업데이트를 할 때는 useState로 상태를 관리해야했지만, React 19에서는 useTransition을 사용해서 pending상태를 관리할 수 있습니다.

function updateNameWithUseTransition({}) {  
	const [name, setName] = useState("");  
	const [error, setError] = useState(null);  
	const [isPending, startTransition] = useTransition();  

	const handleSubmit = () => {
		// startTransition 함수에서 비동기 핸들링
		startTransition(async () => {  
			const error = await updateName(name);  
			if (error) {  
				setError(error);  
				return; 
			}  
			redirect("/path");  
		})  
	};  
	// ...이하 생략
}

useActionState

또한, 비동기 요청 이후의 optimisitic updates, 즉 낙관적 업데이트를 위한 useOptimistic 과 일반적인 처리를 위한 useActionState를 도입했습니다. 이외에 react-dom에서는 form을 자동으로 관리하기 위해 form Action을 추가하고 form Action에 대한 일반적인 경우를 지원하기 위해 useFormStatus를 추가했습니다.

아직은 react-hook-form에 익숙해서 그런지, 눈에 띄게 특별해 보이진 않습니다. 라이브러리를 사용하지 않고, 쉽게 form을 관리하는 점에서 보면 좋을 것 같습니다.

function ChangeNameWithUseActionState({ name, setName }) {  
	const [error, submitAction, isPending] = useActionState(  
		async (previousState, formData) => {  
			const error = await updateName(formData.get("name"));  
			if (error) {  
				return error;  
			}  
			redirect("/path");  
			return null;  
		},  
		null,
	);  
	return (  
		<form action={submitAction}>  
			<input type="text" name="name" />  
			<button type="submit" disabled={isPending}>Update</button>  
			{error && <p>{error}</p>}  
		</form>  
	);  `
}

useActionState에서 상세히 확인할 수 있습니다.

useFormStatus

컴포넌트 깊숙이 전달해야하는 form 상태를 관리하기 위해 useFormStatus도 추가되었습니다.

import {useFormStatus} from 'react-dom';  

function DesignButton() {  
	const {pending} = useFormStatus();  
	return <button type="submit" disabled={pending} />  
}

useFormStatus에서 상세히 확인할 수 있습니다.

useOptimisitc

그리고, useOptimistic으로 낙관적 업데이트를 할 수 있는데, 업데이트 요청 시 먼저 결과를 업데이트하고, 실패하면 이전 상태로 간편하게 돌아갈 수 있습니다.

use

usepromise를 전달하면, promiseresolve될 때까지 reactsuspend 됩니다.

특이한 점은, use는 조건부 렌더링에서도 호출 가능합니다.

import {use} from 'react';  

function Comments({commentsPromise}) {  
	// `use`로 promise를 전달합니다.
	const comments = use(commentsPromise);  
	return comments.map(comment => <p key={comment.id}>{comment}</p>);  
}  

function Page({commentsPromise}) {  
	// Comments가 suspend 되는 동안 Loading 컴포넌트가 출력됩니다.
	return (  
		<Suspense fallback={<div>Loading...</div>}>  
			<Comments commentsPromise={commentsPromise} />  
		</Suspense>  
	)  
}

use에서 상세히 확인할 수 있습니다.


2. React Server Component & Server Action

서버 컴포넌트서버 액션에 대한 내용도 추가되었습니다.

말그대로, 서버 컴포넌트는 서버에서 렌더링되는 컴포넌트이고, 서버 액션은 서버에서 실행되는 함수입니다.

서버 컴포넌트"use server"서버 액션을 정의할 수 있습니다:

// Server Component  

import Button from './Button';  

function EmptyNote () {  
	async function createNoteAction() {
		// 서버 액션  
		'use server';  
		await db.notes.create();  
	}  
	return <Button onClick={createNoteAction}/>;  
}

서버 액션에 관한 자세한 정보는 React Server Actions에서 확인할 수 있습니다.


3. Improvements

ref

더 이상 forwardRef를 감싸지 않아도 ref를 전달받을 수 있습니다.

향후에는 forwardRef는 삭제될 예정입니다.

function MyInput({placeholder, ref}) {  
	return <input placeholder={placeholder} ref={ref} />  
}  
//...  
<MyInput ref={ref} />

Hydration Error 개선

이제 hydration error의 설명이 더 상세해졌습니다.

기존에는 어디에서 오류가 발생한지 직접 찾아야했지만, 이제는 오류가 발생한 컴포넌트를 보여줍니다.

<Context> as a provider

<Context>를 Provider로 사용할 수 있습니다.

향후 버전에서는<Context.Provider>deprecated될 예정입니다.

const ThemeContext = createContext('');

function App({children}) {  
	return (  
		<ThemeContext value="dark">  
			{children}  
		</ThemeContext>  
	);  
}

Document Metadata 지원

React-helmet과 같은 라이브러리를 사용하지 않고, meta 태그를 추가할 수 있도록 지원합니다.

컴포넌트에서 meta 태그를 추가하면, 렌더링 될 때 <head> 섹션으로 자동으로 올라갑니다.

CSR, SSR, Server Component 모두 지원합니다.

function BlogPost({post}) {  
	return (  
		<article>  
			<h1>{post.title}</h1>  
			<title>{post.title}</title>  
			<meta name="author" content="Josh" />  
			<link rel="author" href="https://twitter.com/joshcstory/" />  
			<meta name="keywords" content={post.keywords} />  
			<p>  
			Eee equals em-see-squared...  
			</p>  
		</article>  
	);  
}

이외에 추가적인 변경사항들은 https://react.dev/blog/2024/04/25/react-19 에서 확인할 수 있습니다.