TL;DR

Server Actions の結果に基づいて状態(State)を更新するための React の Hook。React Canary より前のバージョンでは useFormState という名前だった。

仕組み

const [state, formAction] = useActionState(fn, initialState)

第 1 引数に Server Action の関数、第 2 引数に初期状態を渡す。返ってきた formAction を <form> の action に渡す。Server Action は現在の状態と FormData を受け取り、返した値が次の状態になる。

function action(currentState, formData) {
  // ...
  return "next state"
}

React Server Component と Client Component のどちらでも使える。

例

Server Action でエラーを処理し、エラーがあればメッセージを表示する。

// state.ts
export type FormState = {
  message: string | null
}
 
export const initialFormState: FormState = {
  message: null,
}
// action.ts
"use server"
 
export async function updateUser(_: FormState, formData: FormData): Promise<FormState> {
  const session = await getServerSession()
  if (!session) {
    return { message: "未認証です。再度ログインしてください" }
  }
 
  try {
    const { imageUrl, name, screenName, bio } = validateFormData(formData)
    // ユーザ情報を更新する
    revalidateTag(`users/${session.user.id}`)
  } catch (err) {
    return { message: "エラーが発生しました" }
  }
 
  redirect("/profile")
}
// index.tsx
export function MyProfileEditForm({ user, profile }: Props) {
  const [formState, formDispatch] = useActionState(updateUser, initialFormState)
 
  return (
    <form action={formDispatch}>
      {formState?.message && <AlertLabel>{formState.message}</AlertLabel>}
      {/* ... */}
    </form>
  )
}

関連

出典