Accueil / Articles / Envoi de données avec RTK Query : Un guide pratique sur les mutations

Envoi de données avec RTK Query : Un guide pratique sur les mutations

Apprenez à utiliser builder.mutation() dans RTK Query pour envoyer des requêtes POST, gérer les états de chargement et d’erreur, ainsi que pour créer un composant de formulaire fonctionnel.

1875 mots

Introduction

Auparavant, nous avons expliqué comment configurer Redux Toolkit Query (RTK Query) et exécuter des opérations de lecture à l’aide de builder.query(). Cela nous a permis de récupérer des données depuis une API et de les afficher dans une application React sans avoir à écrire manuellement des fonctions useEffect(), useState() ou une logique de récupération personnalisée.

Cependant, la lecture de données n’est qu’une partie du processus lorsqu’on travaille avec des API. La plupart des applications ont également besoin de moyens pour ajouter, modifier ou supprimer des enregistrements sur le serveur.

Examinons quelques scénarios courants :

  • Un formulaire de création de compte envoie les nouvelles informations d’inscription.
  • Une page de connexion envoie des identifiants à valider.
  • Une plateforme de blog publie de nouveaux articles.
  • Un magasin en ligne passe de nouvelles commandes.
  • Une application de tâches enregistre les tâches nouvellement ajoutées.

Chacune de ces actions envoie des informations du client vers le serveur, et cela s’effectue généralement par l’intermédiaire d’une requête HTTP POST.

RTK Query ne traite pas les appels POST comme des requêtes — il les considère comme des mutations.

Cet article explique comment envoyer des données à l’aide de builder.mutation(). Nous analyserons chaque partie du code ainsi que chaque paramètre de configuration afin que vous compreniez non seulement ce qu’il faut saisir, mais aussi pourquoi chaque élément est important.

Comprendre les méthodes HTTP

Une API REST typique expose plusieurs opérations :

Méthode But Exemple
GET Lire des données Récupérer tous les utilisateurs
POST Ajouter de nouvelles données
Créer un utilisateur PUT Écraser une ressource existante Remplacer un enregistrement d’utilisateur PATCH Modifier une partie d’une ressource Changer le nom d’un utilisateur DELETE Supprimer des données Supprimer un utilisateur

Ce guide se concentre sur POST, la méthode utilisée pour créer de nouvelles ressources sur un serveur.

Pourquoi POST n’utilise-t-il pas builder.query() ?

C’est un point de confusion fréquent chez les débutants.

Puisque builder.query() peut récupérer des données, pourquoi cette même fonction ne peut-elle pas envoyer des données au serveur ?

Cela vient du fait que chaque outil a une fonction spécifique.

Requêtes

Les requêtes servent à récupérer des informations.

Exemples typiques :

  • Récupérer des utilisateurs
  • Récupérer des produits
  • Récupérer des commandes
  • Récupérer des articles

Puisque les mêmes données peuvent être demandées à plusieurs reprises, les requêtes mettent automatiquement en cache leurs résultats.

Mutations

Les mutations servent à modifier des données.

Exemples typiques :

  • Créer un utilisateur
  • Mettre à jour un utilisateur
  • Supprimer un utilisateur
  • Se connecter
  • S’inscrire

C’est cette distinction qui explique pourquoi RTK Query gère les mutations séparément des requêtes.

Ce que nous allons construire

Nous allons créer un formulaire de base qui envoie un nouvel utilisateur au serveur.

L’endpoint cible est :

https://jsonplaceholder.typicode.com/users

Et la charge utile envoyée dans le corps de la requête ressemblera à ceci :

{
  "name": "John Doe",
  "email": "john@example.com"
}

Structure du projet

src
│
├── app
│   └── store.js
│
├── services
│   └── api.js
│
├── components
│   └── AddUser.jsx
│
├── App.jsx
│
└── main.jsx

La configuration du store Redux reste telle qu’avant. Tout ce que nous avons à ajouter, c’est une extrémité de mutation ainsi qu’un composant qui gère la soumission du formulaire.

Étape 1 — Créer une extrémité de mutation

Ouvrez le fichier du service API :

src/services/api.js

Ensuite, ajoutez la nouvelle définition d’extrémité à l’intérieur de l’objet endpoints.

import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
export const api = createApi({
  reducerPath: "api",  baseQuery: fetchBaseQuery({
    baseUrl: "https://jsonplaceholder.typicode.com/",
  }),  endpoints: (builder) => ({    addUser: builder.mutation({      query: (newUser) => ({
        url: "users",
        method: "POST",
        body: newUser,
      }),    }),  }),});export const {
  useAddUserMutation,
} = api;

Examinons cette ligne par ligne.

Comprendre builder.mutation()

addUser: builder.mutation({

Tandis que builder.query() est destiné à récupérer des données, builder.mutation() est utilisé chaque fois qu’il faut modifier quelque chose sur le serveur.

Situations courantes où il est utilisé :

  • Création d’utilisateurs
  • Inscription de comptes
  • Connexion
  • Mise à jour de produits
  • Suppression de publications

Chaque fois que votre application écrit ou modifie des données sur le backend, une mutation est l’outil approprié.

Comprendre query()

query: (newUser) => ({

Cette fonction reçoit toutes les données que vous lui transmettez depuis votre code React.

Par exemple, si vous envoyez :

addUser({
  name: "John",
  email: "john@example.com",
});

alors le paramètre nommé

newUser

contiendra :

{
  name: "John",
  email: "john@example.com"
}

Cet objet est ce qui est envoyé en tant que corps de la requête.

Comprendre l’URL

url: "users",

Puisque l’URL de base est configurée comme suit :

https://jsonplaceholder.typicode.com/

RTK Query les combine automatiquement en :

https://jsonplaceholder.typicode.com/users

vous n’avez donc jamais besoin d’écrire vous-même l’adresse complète.

Comprendre la méthode

method: "POST",

Cette ligne indique explicitement à RTK Query d’envoyer une requête POST. Si vous l’omettez, la requête redevient par défaut une requête GET.

Comprendre le corps

body: newUser,

Tout ce qui est stocké dans newUser est transmis en tant que charge utile de la requête, par exemple :

{
  "name": "John",
  "email": "john@example.com"
}

Le serveur reçoit cet objet exactement tel qu’il a été construit.

Étape 2 — Exporter le crochet généré

export const {
  useAddUserMutation,
} = api;

Tout comme les requêtes fournissent un crochet généré automatiquement, comme

useGetUsersQuery()

les mutations génèrent elles-mêmes leur propre crochet automatiquement :

useAddUserMutation()

Vous n’écrivez jamais ce crochet à la main — RTK Query le construit pour vous en fonction du nom de l’endpoint.

Étape 3 — Créer le composant React

Créez un nouveau fichier :

src/components/AddUser.jsx

et ajoutez ce code :

import { useState } from "react";
import { useAddUserMutation } from "../services/api";const AddUser = () => {  const [name, setName] = useState("");
  const [email, setEmail] = useState("");  const [
    addUser,
    {
      isLoading,
      isSuccess,
      error,
    },
  ] = useAddUserMutation();  const handleSubmit = async (e) => {    e.preventDefault();    await addUser({
      name,
      email,
    });    setName("");
    setEmail("");  };  return (
    <form onSubmit={handleSubmit}>      <input
        type="text"
        placeholder="Enter Name"
        value={name}
        onChange={(e) => setName(e.target.value)}
      />      <input
        type="email"
        placeholder="Enter Email"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
      />      <button type="submit">
        Add User
      </button>      {isLoading && <p>Saving...</p>}      {isSuccess && <p>User Added Successfully.</p>}      {error && <p>Something went wrong.</p>}    </form>
  );};export default AddUser;

Décomposons ce qui se passe ici.

Comprendre useAddUserMutation()

const [
  addUser,
  {
    isLoading,
    isSuccess,
    error,
  },
] = useAddUserMutation();

Contrairement aux crochets de requête, les crochets de mutation retournent un tableau plutôt qu’un objet. Le premier élément :

addUser

c’est la fonction que vous appelez pour déclencher la requête, tandis que le deuxième élément est un objet contenant des détails d’état utiles concernant cette requête.

Comprendre addUser()

await addUser({
  name,
  email,
});

L’appel de cette fonction envoie une requête comme celle-ci :

POST /users

portant un chargement JSON de cette forme :

{
  "name": "John",
  "email": "john@example.com"
}

En arrière-plan, ce chargement est utilisé pour créer un enregistrement d’utilisateur entièrement nouveau.

Comprendre les états de mutation

En plus de la fonction déclencheuse, RTK Query vous fournit plusieurs indicateurs d’état qui décrivent ce qui se passe avec la requête.

isLoading

isLoading

Cet indicateur devient true tant que la mutation est en cours, ce qui le rend idéal pour désactiver un bouton de soumission ou afficher un indicateur de chargement jusqu’au retour de la réponse.

isSuccess

isSuccess

Lorsque la demande s’achève sans erreur, cette valeur devient true, vous fournissant ainsi un signal clair pour afficher un message de confirmation ou rediriger l’utilisateur ailleurs.

error

error

Si le serveur répond par une erreur, les détails y sont stockés, vous permettant d’afficher une erreur lisible plutôt qu’une interface défectueuse.

Étape 4 — Afficher le composant

Ouvrez le fichier principal de l’application :

src/App.jsx

et remplacez son contenu par le suivant :

import AddUser from "./components/AddUser";
function App() {
  return <AddUser />;
}export default App;

Ensuite, lancez le serveur de développement :

npm run dev

Remplissez les champs du formulaire et cliquez sur Add User — RTK Query s’occupe de l’envoi de la requête POST à votre place.

Flux complet de la demande

Voici un résumé de ce qui se passe en arrière-plan, depuis la soumission du formulaire jusqu’à la mise à jour de l’état :

User Fills Form
        │
        ▼
Clicks Submit
        │
        ▼
addUser()
        │
        ▼
Generated Mutation Hook
        │
        ▼
RTK Query
        │
        ▼
fetchBaseQuery()
        │
        ▼
POST Request
        │
        ▼
Server Response
        │
        ▼
Mutation State Updates
        │
        ▼
React Re-renders

Remarquez tout ce qui est absent de ce flux :

  • fetch()
  • axios.post()
  • useEffect()
  • État de chargement suivi manuellement
  • État d’erreur suivi manuellement

RTK Query s’occupe de chacun d’eux en arrière-plan.

builder.query() vs builder.mutation()

Savoir quand utiliser chacune de ces méthodes de constructeur est très important.

builder.query() est conçu pour récupérer des données, généralement via des requêtes GET, et il génère des hooks tels que useGetUsersQuery() qui s’exécutent automatiquement dès que le composant est rendu. En revanche, builder.mutation() est destiné à modifier des données au moyen de méthodes comme POST, PUT, PATCH ou DELETE. Il produit des hooks tels que useAddUserMutation() qui ne s’exécutent que lorsque vous appelez explicitement la fonction déclencheuse, et non lors du rendu. En bref, les requêtes servent à lire, tandis que les mutations servent à créer, mettre à jour ou supprimer des données.

Choisir l’outil approprié pour chaque tâche permet de maintenir une logique API cohérente et facile à comprendre.

Bonnes pratiques

Tenez ces directives à l’esprit chaque fois que vous développez une fonctionnalité POST avec RTK Query :

  • Utilisez builder.mutation() chaque fois qu’une opération modifie des données sur le serveur.
  • Gardez les corps des requêtes légers, n’envoyant que les champs dont le backend a réellement besoin.
  • Tenez toujours compte de isLoading, isSuccess et error afin que l’interface paraisse réactive et informative.
  • Choisissez des noms d’extrémités descriptifs tels que addUser, createPost ou registerUser.
  • Vérifiez ce que l’utilisateur a saisi avant de l’envoyer au serveur.
  • Examinez la fonction unwrap() si vous préférez gérer les cas de succès et d’échec à l’aide d’un bloc try...catch dans vos composants.
  • Points clés

    En suivant ce guide, vous avez appris comment :

    • Mettre en place une mutation avec builder.mutation().
    • Connecter une extrémité POST au sein d’une API slice.
    • Envoyer des données JSON à un service backend.
    • Utilisez le hook généré automatiquement useAddUserMutation().
    • Démarrez une requête POST directement depuis un formulaire React.
    • Gérez les états de chargement, de succès et d’erreur sans code générique manuel.
    • Distinguez les requêtes de lecture des requêtes d’écriture.
    • Mettez en pratique des méthodes solides pour créer des interactions API faciles à maintenir.

    Cette même approche apparaît constamment dans les applications en production : processus d’inscription des utilisateurs, authentification, publication de billets de blog, passation de commandes, ainsi que d’innombrables autres scénarios de création de données.

    Que faire ensuite ?

    Après avoir maîtrisé les requêtes POST, l’étape suivante naturelle est d’apprendre à mettre à jour et à supprimer des enregistrements existants.

    Le guide à venir abordera :

    • Mettre à jour des enregistrements avec les requêtes PUT et PATCH.
    • Supprimer des enregistrements via les requêtes DELETE.
    • Transfert d’ID dynamiques vers les points de terminaison de mutation.
    • Invalidation des données mémorisées afin que l’interface utilisateur se mette à jour automatiquement.
    • Utilisation de fonctions — providesTags et invalidatesTags — pour maintenir tout en synchronisation sans avoir à récupérer les données manuellement.

    Lorsque vous aurez terminé ce guide, vous serez en mesure de créer une application CRUD complète en utilisant des modèles RTK Query prêts pour la production.

    Lectures complémentaires