useFormState
useFormState
est un Hook qui vous permet de mettre à jour l’état sur base du résultat d’une action de formulaire.
const [state, formAction] = useFormState(fn, initialState, permalink?);
Référence
useFormState(action, initialState, permalink?)
Appelez useFormState
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 à useFormState
une fonction d’action de formulaire existante ainsi qu’un état initial, et il 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 { useFormState } from "react-dom";
async function increment(previousState, formData) {
return previousState + 1;
}
function StatefulForm({}) {
const [state, formAction] = useFormState(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, useFormState
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
useFormState
renvoie un tableau avec exactement deux 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.
Limitations
- Lorsque vous utilisez un framework prenant en charge les React Server Components,
useFormState
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 à
useFormState
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 àuseFormState
.
Utilisation
Utiliser les informations renvoyées par une action de formulaire
Appelez useFormState
au niveau racine de votre composant pour accéder à la valeur renvoyée par l’action lors du dernier envoi du formulaire.
import { useFormState } from 'react-dom';
import { action } from './actions.js';
function MyComponent() {
const [state, formAction] = useFormState(action, null);
// ...
return (
<form action={formAction}>
{/* ... */}
</form>
);
}
useFormState
renvoie un tableau avec exactement deux valeurs :
- L’état courant du formulaire, qui sera au départ l’état initial que vous aurez fourni, puis une fois le formulaire envoyé, vaudra la valeur de retour de l’action que vous aurez passée.
- Une nouvelle action que vous pouvez passer comme prop
action
à votreform
.
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 useFormState
.
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 à useFormState
.
import { useState } from "react"; import { useFormState } from "react-dom"; import { addToCart } from "./actions.js"; function AddToCartForm({itemID, itemTitle}) { const [message, formAction] = useFormState(addToCart, null); return ( <form action={formAction}> <h2>{itemTitle}</h2> <input type="hidden" name="itemID" value={itemID} /> <button type="submit">Ajouter au panier</button> {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 useFormState
, 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) {
// ...
}