AccueilClientsExpertisesBlogOpen SourceContact

1 octobre 2024

Pourquoi muter le state pose problème en React

3 minutes de lecture

Pourquoi muter le state pose problème en React
🇺🇸 This post is also available in english

Lorsque je donne des formations React, un des bugs récurrents rencontrés par les participants est la mutation du state. C'est un problème souvent subtil, et pour bien le comprendre, il faut saisir la façon dont React gère le state.

Cet article vise à clarifier pourquoi la mutation du state est problématique dans React et comment l'éviter efficacement.

Le problème

Prenons un exemple simple. Vous avez un tableau dans le state que vous souhaitez mettre à jour :

const [items, setItems] = useState([1, 2, 3])

const addItem = () => {
  items.push(4)
  setItems(items) // Oups, on mute le tableau ici
}

En exécutant cette fonction, vous pourriez vous attendre à voir le composant se mettre à jour avec l’élément ajouté. Mais non, rien ne se passe. Pourquoi ? Parce que la référence du tableau items n'a pas changé. Vous avez simplement modifié son contenu, et React ne le détecte pas.

Le résultat : aucune mise à jour de l'UI. Ce que nous venons de faire est une mutation du state.

Comprendre ce qu'est une mutation

Imaginez votre application comme un quartier résidentiel rempli de maisons, où chaque variable est une maison avec sa propre adresse postale. Lorsque vous créez une variable, vous leur attribuez une adresse.

Array

Muter un objet, c’est comme rénover l’intérieur d’une maison sans changer son adresse. Vous pouvez repeindre les murs, ajouter des meubles, mais l'adresse reste la même.

Array

React, de son côté, ne regarde pas l’intérieur des maisons. Il ne se soucie que de savoir si l’adresse a changé. Si l'adresse reste identique, React considère qu'il n'y a aucun changement et ne déclenche pas de mise à jour. C’est ici que muter le state devient problématique : vous modifiez l'intérieur de l'objet, mais React n'en a aucune idée et continue de se baser sur l’ancienne version de l’UI.

Des effets indésirables

Le problème peut aussi survenir dans des hooks comme useEffect, où muter le state peut bloquer l'exécution des side effets. Un exemple classique :

user.username = 'Romy'

useEffect(() => {
  console.log('user has changed!')
}, [user])

Si vous mutez l’objet user au lieu de créer une nouvelle référence, l’effet ne sera jamais rappelé. Ce bug ne génère pas d’erreurs visibles mais des comportements inattendus qui peuvent s'accumuler.

La solution : copier, ne pas muter

Mais alors comment éviter ce problème ? La solution est simple : au lieu de muter vos objets ou tableaux, créez de nouvelles copies avec des opérateurs comme le spread operator (...) ou des méthodes comme concat. Voici comment corriger notre exemple précédent :

const addItem = () => {
  const newItems = [...items, 4] // Nouvelle référence
  setItems(newItems) // Mise à jour du state
}

Ici, on crée un nouveau tableau, ce qui génère une nouvelle référence. React détecte ce changement, et l’UI est mise à jour correctement.


Array

De la même façon, pour les objets :

const updateUser = () => {
  const newUser = { ...user, age: 30 } // Nouvelle référence
  setUser(newUser)
}

À noter que pour les variables simples dites atomiques (string, number, boolean…), nous n'avons pas ce problème de mutation.

Ces types de données sont immuables par nature en JavaScript. Lorsque vous "modifiez" une variable de ce type, vous créez en réalité une nouvelle valeur avec une nouvelle référence. C'est pourquoi React peut détecter les changements sur ces types de données sans difficulté.

Pourquoi tout ça est important ?

React repose sur la comparaison des références pour optimiser les mises à jour de l'UI. Plutôt que d'effectuer une comparaison profonde (qui serait coûteuse en performance), il vérifie simplement si une nouvelle référence a été générée. Si c’est le cas, React sait qu’il doit réconcilier le DOM avec le nouveau state.

Cette optimisation est cruciale pour maintenir des performances acceptables, surtout dans des applications complexes. Comparer chaque propriété d'un objet ou chaque élément d'un tableau à chaque changement de state ralentirait considérablement le rendu. En créant une nouvelle référence, vous garantissez une mise à jour fluide et prévisible.

En résumé

Muter le state, c’est comme refaire la déco d’une maison sans toucher à l'adresse : personne ne remarque les changements. En revanche, créer une nouvelle référence, c’est donner à React la possibilité de faire son travail et de mettre à jour l'UI.

Alors, la prochaine fois que vous gérez du state, souvenez-vous : ne mutez pas, dupliquez !

👋🏼

À découvrir également

AI et UI #1 - Filtres intelligents avec le SDK Vercel AI et Next.js

12 Jun 2024

AI et UI #1 - Filtres intelligents avec le SDK Vercel AI et Next.js

Dans ce premier article d’une série consacrée à l’IA et l’UI, je vous propose de découvrir différentes manières d’intégrer ces modèles d’IA dans vos applications React pour améliorer l’expérience utilisateur.

par

Baptiste

Retour d'expérience chez 20 Minutes : s'adapter au journalisme numérique

30 May 2024

Retour d'expérience chez 20 Minutes : s'adapter au journalisme numérique

Dans cet article, vous ne trouverez pas de snippets ou de tips croustillants sur React, seulement le récit d'une aventure plutôt ordinaire à travers le développement et l'évolution d'un projet technique.

par

Vincent

Améliorez vos composants avec Storybook

17 Nov 2020

Améliorez vos composants avec Storybook

Connaissez-vous Storybook ? Cet outil open-source offre un environnement...

par

Baptiste

Premier Octet vous accompagne dans le développement de vos projets avec react

En savoir plusNous contacter
18 avenue Parmentier
75011 Paris
+33 1 43 57 39 11
hello@premieroctet.com

Suivez nos aventures

GitHub
X (Twitter)
Flux RSS

Naviguez à vue