useActionState - This feature is available in the latest Canary

Canary

Hook useActionState saat ini hanya tersedia di kanal Canary dan eksperimental React. Pelajari lebih lanjut tentang saluran rilis disini. Selain itu, Anda perlu menggunakan framework yang mendukung React Server Components untuk mendapatkan manfaat penuh dari useActionState.

Catatan

Pada versi React Canary sebelumnya, API ini merupakan bagian dari React DOM dan disebut useFormState.

useActionState adalah sebuah Hook yang memungkinkan Anda memperbarui state berdasarkan hasil dari aksi sebuah form.

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

Referensi

useActionState(action, initialState, permalink?)

Panggil useActionState di tingkat atas komponen Anda untuk membuat state komponen yang diperbarui saat aksi form dijalankan. Anda mengoper sebuah fungsi aksi form yang sudah ada serta state awal ke useActionState, dan fungsi ini akan mengembalikan aksi baru yang Anda gunakan dalam form, bersama dengan state form terbaru. State form terbaru juga akan dioper ke fungsi yang Anda sediakan.

import { useActionState } from "react";

async function increment(previousState, formData) {
return previousState + 1;
}

function StatefulForm({}) {
const [state, formAction] = useActionState(increment, 0);
return (
<form>
{state}
<button formAction={formAction}>Increment</button>
</form>
)
}

State form adalah nilai yang dikembalikan oleh aksi saat form terakhir kali disubmit. Jika form belum disubmit, itu adalah state awal yang Anda lewatkan.

Jika digunakan dengan Aksi Server, useActionState memungkinkan respon dari server setelah mengirimkan form untuk ditampilkan bahkan sebelum proses hydrasi selesai.

Lihat contoh lainnya di bawah ini.

Parameter

  • fn: Fungsi yang akan dipanggil ketika form dikirimkan atau tombol ditekan. Ketika fungsi dipanggil, fungsi akan menerima keadaan sebelumnya dari form (awalnya initialState yang Anda berikan, kemudian nilai kembalinya sebelumnya) sebagai argumen awal, diikuti dengan argumen yang biasanya diterima oleh aksi form.
  • initialState: Nilai yang Anda inginkan untuk state awalnya. Nilai ini dapat berupa nilai yang dapat diurutkan. Argumen ini diabaikan setelah aksi pertama kali dipanggil.
  • opsional permalink: String yang berisi URL halaman unik yang dimodifikasi oleh form ini. Untuk digunakan pada halaman dengan konten dinamis (misalnya: feeddalam hubungannya dengan peningkatan progresif: jika fn adalah aksi server dan form dikirimkan sebelum bundel JavaScript dimuat, browser akan menavigasi ke URL permalink yang ditentukanL, bukan ke URL halaman yang sekarang. Pastikan bahwa komponen form yang sama di-render di halaman tujuan (termasuk action fn dan permalink yang sama) sehingga React tahu bagaimana cara meneruskan state. Setelah form di-hidrasi, parameter ini tidak berpengaruh.

Pengembalian

useActionState mengembalikan sebuah array dengan tepat dua nilai:

  1. Keadaan saat ini. Selama render pertama, ini akan cocok dengan initialState yang telah Anda berikan. Setelah aksi dipanggil, ia akan cocok dengan nilai yang dikembalikan oleh aksi.
  2. Tindakan baru yang dapat Anda berikan sebagai prop action ke komponent form Anda atau propformAction ke komponen button mana pun di dalam form.

Perhatian

  • Ketika digunakan dengan framework yang mendukung React Server Components, useActionState memungkinkan Anda membuat form menjadi interaktif sebelum JavaScript dieksekusi di klien. Ketika digunakan tanpa Komponen Server, ini setara dengan state lokal komponen.
  • Fungsi yang dioper ke useActionState menerima argumen tambahan, yaitu state sebelumnya atau awal, sebagai argumen pertamanya. Hal ini membuat tanda tangannya berbeda dibandingkan jika digunakan secara langsung sebagai aksi form tanpa menggunakan useActionState.

Penggunaan

Menggunakan informasi yang dikembalikan oleh tindakan form

Panggil useActionState di tingkat atas komponen Anda untuk mengakses nilai balik dari suatu tindakan dari saat terakhir kali form dikirimkan.

import { useActionState } from 'react';
import { action } from './actions.js';

function MyComponent() {
const [state, formAction] = useActionState(action, null);
// ...
return (
<form action={formAction}>
{/* ... */}
</form>
);
}

useActionState mengembalikan sebuah array dengan tepat dua:

  1. State saat ini dari form, yang pada awalnya diatur ke state awal yang Anda berikan, dan setelah form dikirimkan, diatur ke nilai balik dari aksi yang Anda berikan.
  2. Aksi baru yang Anda oper ke<form> sebagai properti action-nya.

Ketika form dikirimkan, fungsi aksi yang Anda berikan akan dipanggil. Nilai baliknya akan menjadi state saat ini yang baru dari form.

Aksi yang Anda sediakan juga akan menerima argumen pertama yang baru, yaitu state saat ini dari form. Saat form dikirimkan untuk pertama kalinya, nilai akan berupa state awal yang Anda berikan, Pada pengiriman berikutnya, nilai ini akan menjadi hasil dari panggilan aksi terakhir. Sisanya dari argumen tetap sama seperti jika useActionState tidak digunakan.

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

Menampilkan informasi setelah mengirimkan form

Contoh 1 dari 2:
Menampilkan kesalahan form

Untuk menampilkan pesan seperti pesan kesalahan atau toast yang dikembalikan oleh Aksi Server, bungkus aksi tersebut dengan panggilan ke useActionState.

import { useActionState, useState } from "react";
import { addToCart } from "./actions.js";

function AddToCartForm({itemID, itemTitle}) {
  const [message, formAction] = useActionState(addToCart, null);
  return (
    <form action={formAction}>
      <h2>{itemTitle}</h2>
      <input type="hidden" name="itemID" value={itemID} />
      <button type="submit">Add to Cart</button>
      {message}
    </form>
  );
}

export default function App() {
  return (
    <>
      <AddToCartForm itemID="1" itemTitle="JavaScript: The Definitive Guide" />
      <AddToCartForm itemID="2" itemTitle="JavaScript: The Good Parts" />
    </>
  )
}

Pemecahan masalah

Aksi saya tidak lagi dapat membaca data form yang dikirimkan

Ketika Anda membungkus sebuah aksi dengan useActionState, ia mendapatkan argumen tambahan sebagai argumen pertama. Oleh karena itu, data form yang dikirimkan menjadi argumen kedua alih-alih argumen pertama seperti biasanya. Argumen pertama baru yang ditambahkan adalah state saat ini dari form.

function action(currentState, formData) {
// ...
}