Aller au contenu principal

Hooks supplémentaire

Sur cette page, vous trouverez un ensemble de hooks que nous n'avons pas pu voir durant les laboratoires. Ce sont des hooks intéressants, car ils permettent de résoudre certaines problématiques. Vous n'êtes pas obligés de les utiliser, mais je vous conseille de lire une première fois cette page pour prendre connaissance de leur existence et utilité. Si vous pensez qu'un de ces hooks pourraient vous servir, vous pourrez toujours revenir sur cette page plus tard.

useActionState

En React, nous pouvons gérer l'envoie d'un formulaire avec un état local. Lors du click sur le bouton d'envoie, nous faisons généralement les étapes suivantes dans le listener:

  1. Empêcher le comportement par défaut
  2. Changer l'état pour indiquer que l'envoie est en cours
  3. Envoyer les données
  4. Attendre la réponse
  5. Traiter la réponse
  6. Changer l'état pour indiquer que l'envoie est fini et afficher le résultat

Ce qui nous donnerait quelque chose comme ceci:

function Exemple {
const [pending, setPending] = useState(false);

const submit = (e) => {
// 1
e.preventDefault();
// 2
setPening(true);
// 3
sendData(...)
// 4
.then(rep => {
// 5
saveState(rep);
})
.catch(err => {
// 5
saveState(err);
});
// 6
.finally(() => {
setPending(false);
})

}

return (
<form submit={submit}>
...
</form>
);
}

Grâce à ce nouveau hook, le code est simplifié. En effet, celui va gérer la partie "pending" pour nous. Voici la signature de la fonction: const [state, formAction, isPending] = useActionState(fn, initialState, permalink?); Le première paramètre est une fonction fn, nous reviendrons dessus juste après. Le second paramètre est l'état inital avant l'envoie l'envoie des données. Enfin, le dernier paramètre est utilisé dans un cas très spécifique: un rendu côté serveur et l'utilisateur doit cliquer sur le bouton d'envoie avant que le JavaScript ne soit chargé (vous ne serez donc pas concernés).

La fonction fn doit prendre deux arguments: l'état précédent et les données du formulaire sous la forme d'un formData.

Ensuite, pour le tableau renvoyé, nous avons: En première position un état, en deuxième une fonction qui sera utilisée pour soumettre le formulaire et en troisème un boolean qui indique si la soumission est en cours ou non.

Ce qui nous donnerait le code suivant:

unction Exemple {
const [state, formAction, isPending] = useActionState((previousState, formData) => {
// ce qu'il faut faire pour envoyer le formulaire
},
{
// L'état inital
});


return (
<form submit={formAction}>
...
</form>
);
}

useFormStatus

Ce hook permet de connaître l'état du dernier formulaire qui contient le composant. Pratique si vous désirez connaitre l'état du formulaire sans devoir le passer à votre composant. Par exemple: votre composant "Bouton" doit se désactiver pendant la soumission.

Voici sa signature: const { pending, data, method, action } = useFormStatus();

Notez qu'il ne s'agit pas d'un tableau, mais d'un objet.

danger

Attention ! Ce hook n'est utilisable QUE SI votre composant est dans un form !

useTransition

Quand vous utilisez le hook useState, vos changements d'état sont synchrones et seront appliqués les uns après les autres. Ce qui pourrait poser certains problème. Prenons l'exemple de la documentation et mettez à jour rapidement le nombre d'unité:

Dans notre cas, on souhaiterait que la transition soit asynchrone et qu'un seul changement d'état soit appliqué. Une sorte ce cour-circuit si vous voulez, qui permettrait au dernier changement d'état de s'appliquer, annulant les autres.

Le hook useTransition va nous permettre de réaliser ces changements d'états de manière asynchrone. Voici sa signature: const [isPending, startTransition] = useTransition();

  • isPending est un boolean qui indique si la transition (le changement d'état) est en cours
  • startTransition est une fonction avec la signature suivante: ``startTransition(fn)`
    • fn est une fonction synchrone ou asynchrone

Ce qui nous donnerait ceci (exemple de la documentation):

function TabContainer() {
const [isPending, startTransition] = useTransition();
const [tab, setTab] = useState('about');

function selectTab(nextTab) {
startTransition(() => {
setTab(nextTab);
});
}
// ...
}

Quand on sélectionnera un onglet (tab, en anglais), nous appliquerons notre transition qui provoquera le changement d'état asynchrone.

Voici le même exemple, mais avec une transition cette fois:

danger

Vous n'avez aucune garantie de l'ordre des transitions ! La transition n°2 pourrait "court-circuiter" la n°3 si cette dernière se termine avant la 2 ! Voir ici: https://react.dev/reference/react/useTransition#my-state-updates-in-transitions-are-out-of-order

use

Il s'agit d'un nouveau hook permettant de "consommer" une promesse ou un contexte. Contrairement aux autres hooks, il peut être utilisé dans un if ou une boucle. Il peut s'utiliser conjointement à <Suspense>. En effet, tant que la promesse ne sera pas réalisée le composant sera considéré comme "suspendu".

function MessageComponent({ messagePromise }) {
const message = use(messagePromise);
const theme = use(ThemeContext);
// ...

source: https://react.dev/reference/react/use#reference

Ce n'est pas le hook le plus intéressant pour l'instant, mais les équipes de développement ont prévu d'étendre son champs des possibles. Il s'agit surement d'un hook qui continuera d'évoluer au fur et à mesure des mises à jour.