useActionState

useActionState adalah Hook yang memungkinkan Anda memperbarui status berdasarkan hasil aksi formulir.

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

Catatan

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


Referensi

useActionState(action, initialState, permalink?)

Panggil useActionState di tingkat atas komponen Anda untuk membuat state komponen yang diperbarui saat aksi formulir 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 dan apakah aksi tersebut masih tertunda. 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 Fungsi Server, useActionState memungkinkan respon dari server setelah mengirimkan form untuk ditampilkan bahkan sebelum proses hidrasi 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 kembalian 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: feed) dalam hubungannya dengan peningkatan progresif: jika fn adalah fungsi server dan form dikirimkan sebelum bundel JavaScript dimuat, browser akan menavigasi ke URL permalink yang ditentukan, 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.

Kembalian

useActionState returns an array with the following values:

  1. State saat ini. Selama render pertama, ini akan dicocokkan dengan initialState yang telah Anda berikan. Setelah aksi dipanggil, ia akan dicocokkan dengan nilai yang dikembalikan oleh aksi.
  2. Aksi baru yang dapat Anda berikan sebagai prop action ke komponen form Anda atau formAction ke komponen button manapun di dalam formulir. Aksi dapat juga dipanggil secara manual dari dalam startTransition.
  3. Flag isPending yang memberitahu apakah ada Transisi yang masih tertunda.

Catatan penting

  • Ketika digunakan dengan framework yang mendukung Komponen Server React, 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 nilai berikut:

  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 atau dipanggil secara manual dari dalam startTransition.
  3. State tertunda yang dapat Anda manfaatkan saat aksi Anda sedang diproses.

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 Fungsi 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, isPending] = useActionState(addToCart, null);
  return (
    <form action={formAction}>
      <h2>{itemTitle}</h2>
      <input type="hidden" name="itemID" value={itemID} />
      <button type="submit">Add to Cart</button>
      {isPending ? "Loading..." : 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) {
// ...
}