useActionState

Odyssey·2025년 7월 19일
0

Next.js_study

목록 보기
58/58
post-thumbnail

2025.7.19 토요일의 공부기록

React 19에서는 form + Server Action 패턴의 상태 관리를 위한 새로운 훅 useActionState 가 정식으로 도입되었다.
기존 Canary 빌드에서 제공되던 useFormState 는 React 19에서 이름과 기능이 확장되어 useActionState 로 변경되었으며, 서버 액션과 긴밀하게 연동된다.


useActionState 이란?

useActionState서버 액션(Form Action)의 결과를 기반으로 클라이언트 컴포넌트의 상태(state)를 업데이트 하도록 설계된 React 19 전용 Hook이다.

  • 서버로 폼이 제출되면, 서버 액션의 응답을 이용해 즉시 상태를 업데이트할 수 있다.
  • 로딩 상태(isPending)를 함께 제공하여 UX를 단순화한다.
  • React 19 이전 Canary 버전의 useFormState 보다 공식·안정화된 API이다.

🔗 React 공식 문서 – useActionState
https://ko.react.dev/reference/react/useActionState


🔍 시그니처 & 매개변수

const [state, formAction, isPending] =
    useActionState(fn, initialState, permalink?);
매개변수설명필수
fn서버 액션으로 동작할 비동기 함수필수
initialStateHook이 처음 가질 상태(기본값)필수
permalink(선택) 고정된 URL(퍼머링크)을 서버 액션에 전달아님

반환값설명
state서버 액션 처리 후 업데이트된 상태
formAction<form action={formAction}> 로 연결되는 액션 함수
isPending액션이 실행 중인지 여부 (로딩 Boolean)

useFormStateuseActionState 변경사항

React Canary (이전)React 19 정식 (현재)
useFormStateuseActionState
DOM 기반 상태 전파서버 액션 결과 기반 상태 전파
실험적 API안정화·공식 API

예시 코드

클라이언트 컴포넌트 예시

아래 예시는 제품 업로드 폼에서 useActionState를 사용해 서버 액션 결과를 처리하는 기본 패턴이다.

"use client";

import { useActionState } from "react";
import { uploadProduct } from "@/app/products/add/actions";

const initialState = { error: null };

export default function ProductForm() {
  const [state, formAction, isPending] =
    useActionState(uploadProduct, initialState);

  return (
    <form action={formAction}>
      <input type="text" name="title" placeholder="제품명" required />
      <input type="number" name="price" placeholder="가격" required />
      <input type="file" name="photo" required />
      <textarea name="description" placeholder="설명" required />
      <button type="submit" disabled={isPending}>
        {isPending ? "업로드 중..." : "제품 업로드"}
      </button>

      {state.error && <p style={{ color: "red" }}>
        {JSON.stringify(state.error)}
      </p>}
    </form>
  );
}

서버 액션 함수 예시

"use server";

import { z } from "zod";

export async function uploadProduct(prevState: any, formData: FormData) {
  // Zod 검증 (예시)
  const schema = z.object({
    title: z.string().min(1),
    price: z.coerce.number().positive(),
  });

  const result = schema.safeParse({
    title: formData.get("title"),
    price: formData.get("price"),
  });

  if (!result.success) {
    return { error: result.error.flatten() };
  }

  // 성공 시 DB 저장 또는 다른 로직 수행
  return { success: true };
}

단,

  • useActionStateReact 19 이상 버전에서만 동작한다.
  • 이전 프로젝트에서 useFormState를 사용 중이라면, React 19 업데이트 후 함수명을 변경해야 한다.
  • 서버 액션 함수(fn)는 항상 async 함수여야 하며, 첫 매개변수(prevState)로 기존 상태를 받을 수 있다.

0개의 댓글