useActionState
useActionState
est un Hook qui vous permet de mettre à jour l’état sur base du résultat d’une action de formulaire.
const [state, formAction, isPending] = useActionState(fn, initialState, permalink?);
Référence
useActionState(action, initialState, permalink?)
Appelez useActionState
au niveau racine de votre composant pour créer un état de composant qui sera mis à jour lorsqu’une action de formulaire sera invoquée. Vous passez à useActionState
une fonction d’action de formulaire existante ainsi qu’un état initial, et elle renvoie une nouvelle action que vous pouvez utiliser dans votre formulaire, ainsi que le dernier état en date pour ce formulaire. Cet état sera également passé à la fonction que vous avez fournie.
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}>Incrémenter</button>
</form>
)
}
L’état de formulaire est déterminé par la valeur renvoyée par l’action lors du dernier envoi en date du formulaire. Si le formulaire n’a pas encore été envoyé, il équivaut à l’état initial que vous avez fourni.
Lorsque vous l’utilisez dans une Action Serveur, useActionState
permet d’afficher la réponse du serveur pour l’envoi du formulaire avant même que l’hydratation ne soit terminée.
Voir d’autres exemples plus bas.
Paramètres
fn
: la fonction à appeler lorsque le formulaire est envoyé. Lorsque la fonction est appelée, elle reçoit comme premier argument l’état précédent du formulaire (leinitialState
que vous avez fourni pour le premier appel, puis, pour les appels ultérieurs, la valeur précédemment renvoyée), suivi par les arguments normalement acceptés par une fonction d’action de formulaire.initialState
: la valeur initiale que vous souhaitez pour votre état. Il peut s’agir de n’importe quelle valeur sérialisable. Cet argument est ignoré après l’appel initial de l’action.permalink
optionnel : une chaîne de caractères contenant l’URL unique de la page que ce formulaire modifie. Conçu pour une utilisation sur des pages à contenu dynamique (telles que des flux) pour permettre une amélioration progressive : sifn
est une Action Serveur et que le formulaire est soumis avant que le bundle JavaScript n’ait fini son chargement, le navigateur ira sur l’URL de permalien fournie, plutôt que sur l’URL de la page courante. Ça permet de garantir que le même composant de formulaire sera produit sur la page destinataire (y compris les infosfn
etpermalink
), afin que React sache comment lui passer l’état. Une fois le formulaire hydraté, ce paramètre n’a plus d’effet.
Valeur renvoyée
useActionState
renvoie un tableau avec exactement trois valeurs :
- L’état courant. Lors du rendu initial, il s’agira du
initialState
que vous avez passé. Après que l’action aura été invoquée, il correspondra à la valeur renvoyée par l’action. - Une nouvelle action que vous pouvez passer comme prop
action
à votre composantform
, ou comme propformAction
à tout composantbutton
au sein du formulaire. - Le drapeau
isPending
qui vous indique si une Transition est en cours.
Limitations
- Lorsque vous utilisez un framework prenant en charge les React Server Components,
useActionState
vous permet de rendre les formulaires interactifs avant même que JavaScript ne soit exécuté côté client. Si vous l’utilisez hors des Server Components, il est équivalent à un état local de composant. - La fonction passée à
useActionState
reçoit un premier argument supplémentaire : l’état précédent ou initial. Sa signature est donc différente de celles des fonctions d’action de formulaire utilisées directement par vos formulaires, sans recours àuseActionState
.
Utilisation
Utiliser les informations renvoyées par une action de formulaire
Appelez useActionState
au niveau racine de votre composant pour accéder à la valeur renvoyée par l’action lors du dernier envoi du formulaire.
import { useActionState } from 'react';
import { action } from './actions.js';
function MyComponent() {
const [state, formAction] = useActionState(action, null);
// ...
return (
<form action={formAction}>
{/* ... */}
</form>
);
}
useActionState
renvoie un tableau avec exactement trois valeurs :
- L’état courant du formulaire, qui sera au départ l’état initial que vous aurez fourni, puis une fois le formulaire envoyé, aura la valeur de retour de l’action que vous aurez passée.
- Une nouvelle action que vous pouvez passer comme prop
action
à votreform
. - Un état d’attente que vous pouvez utiliser tandis que l’action est en cours de traitement.
Lorsque le formulaire sera envoyé, la fonction d’action que vous aurez fournie sera appelée. Sa valeur de retour deviendra le nouvel état courant du formulaire.
L’action que vous aurez fournie recevra par ailleurs un premier argument supplémentaire, à savoir l’état courant du formulaire. Lors du premier envoi du formulaire, il s’agira de l’état initial que vous aurez fourni, alors que pour les envois ultérieurs, ce sera la valeur renvoyée par le dernier appel en date de l’action. Le reste des arguments est identique à une utilisation de l’action sans useActionState
.
function action(currentState, formData) {
// ...
return 'prochain état';
}
Exemple 1 sur 2 · Afficher des erreurs de formulaire
Pour afficher des messages tels qu’un message d’erreur ou une notification renvoyés par une Action Serveur, enrobez l’action dans un appel à 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">Ajouter au panier</button> {isPending ? "Chargement en cours..." : message} </form> ); } export default function App() { return ( <> <AddToCartForm itemID="1" itemTitle="JavaScript: The Definitive Guide" /> <AddToCartForm itemID="2" itemTitle="JavaScript: The Good Parts" /> </> ) }
Dépannage
Mon action n’arrive plus à lire les données envoyées par le formulaire
Lorsque vous enrobez une action avec useActionState
, elle reçoit un premier argument supplémentaire. Les données envoyées par le formulaire sont donc présentes comme second argument, plutôt qu’en première position comme en temps normal. Le premier argument ainsi injecté contient l’état actuel du formulaire.
function action(currentState, formData) {
// ...
}