๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
WEB/REACT

React v19

by mingzoo 2025. 4. 16.

โœ… useActionState: ReactDOM.useFormState → ์ด๋ฆ„ ๋ณ€๊ฒฝ + ๊ธฐ๋Šฅ ๊ฐ•ํ™”

useActionState๋Š” ์„œ๋ฒ„ ์•ก์…˜(server actions)์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค๊ณ„๋œ ํ›…์ž…๋‹ˆ๋‹ค.

์›๋ž˜๋Š” ReactDOM.useFormState๋ผ๋Š” ์ด๋ฆ„์ด์—ˆ์œผ๋‚˜ React v19์—์„œ useActionState๋กœ ๋ณ€๊ฒฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

tsx
๋ณต์‚ฌํŽธ์ง‘
const [state, formAction] = useActionState(myAction, initialState);

์ด ํ›…์€ ํด๋ผ์ด์–ธํŠธ์—์„œ ํผ ์•ก์…˜์„ ์ฒ˜๋ฆฌํ•  ๋•Œ, ์„œ๋ฒ„์™€์˜ ์ธํ„ฐ๋ž™์…˜ ์ƒํƒœ(๋กœ๋”ฉ, ์„ฑ๊ณต, ์‹คํŒจ ๋“ฑ)๋ฅผ ๊ด€๋ฆฌํ•ด์ฃผ๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. ์ค‘์š”ํ•œ ์ ์€ action์ด ์„ฑ๊ณตํ•˜๋ฉด ํผ์„ ์ž๋™์œผ๋กœ resetํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋” ์ด์ƒ e.preventDefault() → fetch → ์ƒํƒœ ์—…๋ฐ์ดํŠธ ๋“ฑ์˜ ๋ฐ˜๋ณต ์ž‘์—…์„ ์ˆ˜๋™์œผ๋กœ ์ž‘์„ฑํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.


๐Ÿ†š ๊ธฐ์กด์˜ react-query์™€ ์–ด๋–ค ์ฐจ์ด๊ฐ€ ์žˆ์„๊นŒ?

ํ•ญ๋ชฉ useAction react-query
๋ชฉ์  ์ฃผ๋กœ ํผ ์•ก์…˜ ์ฒ˜๋ฆฌ์™€ ์„œ๋ฒ„์™€์˜ ์ธํ„ฐ๋ž™์…˜ ์„œ๋ฒ„์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด์˜ค๊ธฐ(fetch)
๋ฆฌ๋ Œ๋”๋ง useActionState๋Š” ํผ ์ œ์ถœ ํ›„ ์ƒํƒœ๋ฅผ ์ž๋™์œผ๋กœ ๊ด€๋ฆฌ react-query๋Š” ์ฃผ๋กœ ๋ฐ์ดํ„ฐ ์บ์‹ฑ ์ค‘์‹ฌ
๋™์ž‘๋ฐฉ์‹ ์„œ๋ฒ„ ์•ก์…˜ ๊ธฐ๋ฐ˜ - ์„œ๋ฒ„์™€ ์—ฐ๊ฒฐ๋œ ํ•จ์ˆ˜ ์‹คํ–‰ ํด๋ผ์ด์–ธํŠธ ์ค‘์‹ฌ - fetch, mutation
reset ๊ธฐ๋Šฅ ์„ฑ๊ณต ์‹œ ์ž๋™์œผ๋กœ form reset ์ˆ˜๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•จ
SSR/Fullstack ์ตœ์ ํ™” โœ… (์„œ๋ฒ„ ์•ก์…˜๊ณผ ์—ฐ๋™๋จ) โŒ (ํด๋ผ์ด์–ธํŠธ ์ค‘์‹ฌ ๋„๊ตฌ)

์ •๋ฆฌํ•˜์ž๋ฉด, useActionState๋Š” ํผ ์ค‘์‹ฌ ์„œ๋ฒ„ ์•ก์…˜ ์ฒ˜๋ฆฌ์— ํŠนํ™”๋˜์–ด ์žˆ๊ณ , react-query๋Š” REST/GraphQL ๊ธฐ๋ฐ˜์˜ ๋ฐ์ดํ„ฐ ํŒจ์นญ์— ํŠนํ™”๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

์šฉ๋„๊ฐ€ ์•„์˜ˆ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.


๐Ÿ†• useFormStatus: ๋” ์ด์ƒ props drilling์€ ์—†๋‹ค

๊ธฐ์กด ๋ฌธ์ œ์ 

ํผ์˜ isSubmitting, isPending ๊ฐ™์€ ์ƒํƒœ๋ฅผ ๋ฒ„ํŠผ์ด๋‚˜ ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ์—์„œ ์•Œ๊ณ  ์‹ถ์„ ๋•Œ, props๋ฅผ ๊ณ„์† ์ „๋‹ฌํ•˜๊ฑฐ๋‚˜, Context๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค.

์ƒˆ ๊ธฐ๋Šฅ

์ด์ œ๋Š” useFormStatus ํ›…์„ ํ†ตํ•ด ํผ ์•ˆ์˜ ์–ด๋–ค ์œ„์น˜์—์„œ๋„ ํ˜„์žฌ ํผ์˜ ์ƒํƒœ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

tsx
๋ณต์‚ฌํŽธ์ง‘
"use client"; import { useFormStatus } from "react-dom"; function SubmitButton() { const { pending } = useFormStatus(); return <button disabled={pending}>Submit</button>; }

React ๋‚ด๋ถ€์—์„œ ์ƒํƒœ ๊ณต์œ ๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ตฌ์กฐ๊ฐ€ ๊น”๋”ํ•ด์ง€๊ณ  ์ฝ”๋“œ ์ž‘์„ฑ์ด ๋‹จ์ˆœํ•ด์ง‘๋‹ˆ๋‹ค.


๐Ÿ”„ useOptimistic: ๋‚™๊ด€์  UI ์—…๋ฐ์ดํŠธ๊ฐ€ ๋” ์‰ฌ์›Œ์กŒ๋‹ค

์„œ๋ฒ„ ์•ก์…˜์„ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๋™์•ˆ, ๋‚™๊ด€์  UI(optimistic UI)๋ฅผ ๋ณด์—ฌ์ฃผ๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ํ›…์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋Œ“๊ธ€์„ ์ž‘์„ฑํ•˜๋ฉด, ์„œ๋ฒ„ ์‘๋‹ต ์ „์— ๋Œ“๊ธ€์ด ๋จผ์ € ํ™”๋ฉด์— ๋ณด์ด๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

tsx
๋ณต์‚ฌํŽธ์ง‘
const [optimisticComments, addOptimisticComment] = useOptimistic(comments);

๊ธฐ์กด์—๋Š” useState์™€ react-query์˜ onMutate, rollback, onError ๋“ฑ์„ ์กฐํ•ฉํ•ด์„œ ์จ์•ผ ํ–ˆ์ง€๋งŒ, ์ด์ œ๋Š” ๊ฐ„๋‹จํ•˜๊ฒŒ useOptimistic๋งŒ์œผ๋กœ ๊ตฌํ˜„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.


๐Ÿ’ก ref prop: forwardRef ์—†์ด๋„ ref ์ „๋‹ฌ์ด ๊ฐ€๋Šฅํ•ด์กŒ๋‹ค

React v19์—์„œ๋Š” ref๋ฅผ props๋กœ ์ง์ ‘ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์ด ๋„์ž…๋ฉ๋‹ˆ๋‹ค.
๊ธฐ์กด์—๋Š” ์ปดํฌ๋„ŒํŠธ ๊ฐ„ ref ์ „๋‹ฌ์„ ์œ„ํ•ด ๋ฐ˜๋“œ์‹œ forwardRef๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ–ˆ์ง€๋งŒ, ์ด์ œ๋Š” ๋‹จ์ˆœํžˆ ref๋ฅผ prop์œผ๋กœ ๋„˜๊ฒจ๋„ ๋ฉ๋‹ˆ๋‹ค.

tsx
๋ณต์‚ฌํŽธ์ง‘
<MyComponent ref={myRef} />

์ด๋Š” React๊ฐ€ ๋‚ด๋ถ€์ ์œผ๋กœ ref๋ฅผ ํŠน๋ณ„ ์ทจ๊ธ‰ํ•˜์ง€ ์•Š๊ณ , ์ผ๋ฐ˜ props์ฒ˜๋Ÿผ ๋‹ค๋ฃจ๊ธฐ ์‹œ์ž‘ํ–ˆ๋‹ค๋Š” ๋œป์ด๋ฉฐ, ์ฝ”๋“œ ๊ตฌ์กฐ๊ฐ€ ๋” ๋‹จ์ˆœํ•ด์ง€๊ณ  ์ปดํฌ๋„ŒํŠธ ์žฌ์‚ฌ์šฉ์„ฑ์ด ํ–ฅ์ƒ๋ฉ๋‹ˆ๋‹ค.


๐Ÿ“ React๋Š” Fullstack์œผ๋กœ ์ง„ํ™” ์ค‘

React 19์—์„œ ์†Œ๊ฐœ๋œ ๊ธฐ๋Šฅ๋“ค์€ ๋‹จ์ˆœํžˆ UI ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋” ์‰ฝ๊ฒŒ ๋งŒ๋“ค์ž๋Š” ์ˆ˜์ค€์ด ์•„๋‹ˆ๋ผ, ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ์˜ ๊ฒฝ๊ณ„๋ฅผ ํ—ˆ๋ฌผ๊ณ , ์ „์ฒด์ ์ธ Fullstack ์•„ํ‚คํ…์ฒ˜๋ฅผ React ๋‚ด๋ถ€๋กœ ํก์ˆ˜ํ•˜๋ ค๋Š” ์˜๋„๊ฐ€ ๊ฐ•ํ•˜๊ฒŒ ๋“œ๋Ÿฌ๋‚ฉ๋‹ˆ๋‹ค.

๋ณ€ํ™” ์˜๋ฏธ
useActionState ์„œ๋ฒ„ ์•ก์…˜ ๊ด€๋ฆฌ (Mutations)
useFormStatus Form ์ƒํƒœ ๊ด€๋ฆฌ์˜ ๋‹จ์ˆœํ™”
useOptimistic ์„œ๋ฒ„-ํด๋ผ์ด์–ธํŠธ UI ๋™๊ธฐํ™”์˜ ๊ฐœ์„ 
ref prop ๊ฐœ์„  ์ปดํฌ๋„ŒํŠธ ์žฌ์‚ฌ์šฉ๊ณผ ํ™•์žฅ์„ฑ ํ–ฅ์ƒ

๋งˆ๋ฌด๋ฆฌํ•˜๋ฉฐ

React 19๋Š” ๊ธฐ์กด์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ƒํƒœ๊ณ„์— ์˜์กดํ•˜๋˜ ๋งŽ์€ ๊ธฐ๋Šฅ๋“ค์„ React ๋‚ด๋ถ€๋กœ ๊ฐ€์ ธ์˜ค๋ฉด์„œ, ๋” ์˜ˆ์ธก ๊ฐ€๋Šฅํ•˜๊ณ  ์ผ๊ด€๋œ ๊ฐœ๋ฐœ ๋ฐฉ์‹์„ ์ œ์•ˆํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
Fullstack React๊ฐ€ ๊ฐ€๋Šฅํ•ด์ง€๋ฉด์„œ Next.js, Server Actions, Server Components์™€์˜ ๊ฒฐํ•ฉ๋ ฅ๋„ ํ›จ์”ฌ ๊ฐ•ํ•ด์กŒ์Šต๋‹ˆ๋‹ค.

์•ž์œผ๋กœ React๋ฅผ ๋‹จ์ˆœํ•œ View ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ๋ณด๋Š” ์‹œ์„ ์€ ์ ์  ์ค„์–ด๋“ค ๊ฒƒ์œผ๋กœ ๋ณด์ด๋ฉฐ,
React ์ƒํƒœ๊ณ„์˜ ๋ณ€ํ™”์— ๋ฏผ๊ฐํ•˜๊ฒŒ ๋ฐ˜์‘ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ด์งˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

728x90