<StrictMode>
<StrictMode>
vous permet de détecter des bugs courants dans vos composants pendant la phase de développement.
<StrictMode>
<App />
</StrictMode>
Référence
<StrictMode>
Utilisez StrictMode
pour activer des comportements de développement et des avertissements supplémentaires pour l’arbre des composants que vous placez à l’intérieur :
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
const root = createRoot(document.getElementById('root'));
root.render(
<StrictMode>
<App />
</StrictMode>
);
Voir d’autres exemples plus bas.
Les comportements suivants sont activés en développement par le mode strict :
- Vos composants feront un rendu supplémentaire afin de trouver les bugs causés par des rendus impurs.
- Vos composants exécuteront les Effets une fois supplémentaire afin de détecter les bugs causés par l’absence de nettoyage d’Effet.
- Vos composants seront contrôlés pour l’utilisation d’API dépréciées.
Props
StrictMode
ne prend aucune prop.
Limitations
- Il n’est pas possible de désactiver le mode strict au sein d’un arbre enrobé dans un
<StrictMode>
. Ça vous garantit que tous les composants à l’intérieur de<StrictMode>
sont vérifiés. Si deux équipes travaillant sur un produit ne sont pas d’accord sur l’utilité de ces vérifications, elles doivent trouver un consensus ou déplacer le<StrictMode>
plus bas dans l’arbre.
Utilisation
Activer le mode strict pour toute l’appli
Le mode strict active des vérifications supplémentaires uniquement en mode de développement pour tout l’arbre des composants à l’intérieur du composant <StrictMode>
. Ces vérifications vous aident à trouver des bugs courants dans vos composants dès le début de la phase de développement.
Pour activer le mode strict pour toute votre appli, enrobez votre composant racine avec <StrictMode>
lorsque vous en faites le rendu :
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
const root = createRoot(document.getElementById('root'));
root.render(
<StrictMode>
<App />
</StrictMode>
);
Nous recommandons d’enrober toute votre appli dans le mode strict, en particulier pour les nouvelles applis. Si vous utilisez un framework qui appelle createRoot
à votre place, consultez sa documentation pour savoir comment activer le mode strict.
Bien que les vérifications en mode strict ne s’exécutent que durant le développement, elles vous aident à trouver des bugs qui existent déjà dans votre code et qui peuvent être difficiles à reproduire de façon fiable en production. Le mode strict vous permet de corriger les bugs avant que vos utilisateurs ne les signalent.
Activer le mode strict sur une partie de l’appli
Vous pouvez également activer le mode strict sur n’importe quelle partie de votre application :
import { StrictMode } from 'react';
function App() {
return (
<>
<Header />
<StrictMode>
<main>
<Sidebar />
<Content />
</main>
</StrictMode>
<Footer />
</>
);
}
Dans cet exemple, les vérifications du mode strict ne s’exécuteront pas sur les composants Header
et Footer
. Cependant, elles s’exécuteront sur Sidebar
et Content
, ainsi que sur tous les composants qu’ils contiennent, peu importe la profondeur à laquelle ils se trouvent.
Corriger les bugs trouvés par le double rendu en développement
React part du principe que chaque composant que vous écrivez est une fonction pure. Ça signifie que vos composants React doivent toujours renvoyer le même JSX pour les mêmes entrées (props, état et contexte).
Les composants qui ne respectent pas cette règle peuvent se comporter de façon imprévisible et occasionner des bugs. Pour vous aider à trouver du code accidentellement impur, le mode strict appelle certaines de vos fonctions (seulement celles qui doivent être pures) deux fois en développement. Ça inclut :
- Le corps de votre fonction composant (seulement la logique du niveau racine, ce qui exclut le code contenu dans les gestionnaires d’événements).
- Les fonctions que vous passez à
useState
, aux fonctionsset
, àuseMemo
ou àuseReducer
. - Certaines méthodes des composants à bases de classes comme
constructor
,render
,shouldComponentUpdate
(voir la liste complète).
Si une fonction est pure, l’exécuter deux fois ne change pas son comportement, car une telle fonction produit le même résultat à chaque fois. Cependant, si une fonction est impure (elle modifie par exemple la donnée qu’elle reçoit), l’exécuter deux fois devrait se remarquer (c’est ce qui la rend impure !). Ça vous aide à détecter et corriger les bugs plus rapidement.
Voici un exemple qui illustre comment le double rendu en mode strict vous aide à détecter des bugs plus tôt.
Ce composant StoryTray
prend un tableau de stories
et ajoute à la fin un élément « Créer une histoire » :
export default function StoryTray({ stories }) { const items = stories; items.push({ id: 'create', label: 'Créer une histoire' }); return ( <ul> {items.map(story => ( <li key={story.id}> {story.label} </li> ))} </ul> ); }
Il y a une erreur dans le code ci-dessus. Il est cependant facile de passer à côté, dans la mesure où l’affichage initial semble correct.
Cette erreur devient bien plus facile à remarquer lorsque le composant StoryTray
fait son rendu plusieurs fois. Par exemple, faisons un nouveau rendu de StoryTray
avec une couleur de fond différente à chaque fois que vous le survolez :
import { useState } from 'react'; export default function StoryTray({ stories }) { const [isHover, setIsHover] = useState(false); const items = stories; items.push({ id: 'create', label: 'Créer une histoire' }); return ( <ul onPointerEnter={() => setIsHover(true)} onPointerLeave={() => setIsHover(false)} style={{ backgroundColor: isHover ? '#ddd' : '#fff' }} > {items.map(story => ( <li key={story.id}> {story.label} </li> ))} </ul> ); }
Remarquez qu’à chaque fois que vous survolez le composant StoryTray
, ça ajoute « Créer une histoire » à la liste. Le code ne visait qu’à l’ajouter une seule fois à la fin. Cependant, StoryTray
modifie directement le tableau stories
des props. Chaque fois que StoryTray
fait son rendu, il ajoute « Créer une histoire » à la fin de ce tableau. En d’autres termes, StoryTray
n’est pas une fonction pure — l’exécuter plusieurs fois produit des résultats différents.
Pour corriger ce problème, vous pouvez faire une copie du tableau et modifier cette copie plutôt que l’original :
export default function StoryTray({ stories }) {
const items = stories.slice(); // Copier le tableau
// ✅ Correct : ajouter dans un nouveau tableau
items.push({ id: 'create', label: 'Créer une histoire' });
Ça rendrait la fonction StoryTray
pure. À chaque appel, elle ne modifierait que la copie du tableau et n’affecterait aucun objet ou variable externe. Ça résout le bug, mais vous avez dû faire en sorte que le composant fasse plus souvent son rendu pour mettre en évidence le souci dans son comportement.
Dans cet exemple, le bug ne sautait pas aux yeux. Enrobons maintenant le code original (avec son bug) dans un composant <StrictMode>
:
export default function StoryTray({ stories }) { const items = stories; items.push({ id: 'create', label: 'Créer une histoire' }); return ( <ul> {items.map(story => ( <li key={story.id}> {story.label} </li> ))} </ul> ); }
Le mode strict appelle toujours votre fonction de rendu deux fois, afin que vous puissiez voir le problème immédiatement (« Créer une histoire » apparaît deux fois). Ça vous permet de détecter ce genre d’erreur plus tôt dans le processus de développement. Lorsque vous corrigez votre composant pour qu’il fasse des rendus corrects en mode strict, vous corrigez également de nombreux bugs potentiels en production, telle que la fonctionnalité de survol précédente :
import { useState } from 'react'; export default function StoryTray({ stories }) { const [isHover, setIsHover] = useState(false); const items = stories.slice(); // Copier le tableau items.push({ id: 'create', label: 'Créer une histoire' }); return ( <ul onPointerEnter={() => setIsHover(true)} onPointerLeave={() => setIsHover(false)} style={{ backgroundColor: isHover ? '#ddd' : '#fff' }} > {items.map(story => ( <li key={story.id}> {story.label} </li> ))} </ul> ); }
Sans le mode strict, il était facile de passer à côté du bug jusqu’à ce que vous ajoutiez d’autres rendus. Le mode strict fait apparaître le même bug immédiatement. Ce mode vous aide à trouver les bugs avant que vous ne les poussiez à votre équipe et à vos utilisateurs.
Apprenez-en davantage sur la façon de garder les composants purs.
Corriger les bugs trouvés en réexécutant les Effets en développement
Le mode strict est également utile pour trouver des bugs dans les Effets.
Chaque Effet a du code d’initialisation et peut avoir du code de nettoyage. Normalement, React appelle le code d’initialisation quand le composant est monté (quand il est ajouté à l’écran), et appelle le code de nettoyage quand le composant est démonté (il est enlevé de l’écran). React appelle ensuite le nettoyage et l’initialisation à nouveau si l’une des dépendances de l’Effet a changé depuis le dernier rendu.
Quand le mode strict est activé, React exécutera un cycle d’initialisation + nettoyage supplémentaire en développement pour chaque Effet. Ça peut surprendre, mais ça aide à détecter des bugs subtils qu’il est difficile de repérer manuellement.
Voici un exemple qui illustre comment la réexécution de l’Effet en mode strict vous aide à trouver des bugs plus rapidement.
Prenez cet exemple qui connecte un composant à un salon de discussion :
import { useState, useEffect } from 'react'; import { createConnection } from './chat.js'; const serverUrl = 'https://localhost:1234'; const roomId = 'general'; export default function ChatRoom() { useEffect(() => { const connection = createConnection(serverUrl, roomId); connection.connect(); }, []); return <h1>Bienvenue sur le salon {roomId} !</h1>; }
Il y a un problème avec ce code, mais ça ne saute pas aux yeux.
Pour rendre le problème plus évident, ajoutons une fonctionnalité. Dans l’exemple ci-dessous, roomId
n’est pas codé en dur. L’utilisateur peut en effet choisir dans une liste déroulante le roomId
auquel il souhaite se connecter. Appuyez sur « Ouvrir le salon » puis sélectionnez un à un les différents salons de discussion. Surveillez le nombre de connexions actives dans la console :
import { useState, useEffect } from 'react'; import { createConnection } from './chat.js'; const serverUrl = 'https://localhost:1234'; function ChatRoom({ roomId }) { useEffect(() => { const connection = createConnection(serverUrl, roomId); connection.connect(); }, [roomId]); <h1>Bienvenue sur le salon {roomId} !</h1>; } export default function App() { const [roomId, setRoomId] = useState('general'); const [show, setShow] = useState(false); return ( <> <label> Choisissez le salon :{' '} <select value={roomId} onChange={e => setRoomId(e.target.value)} > <option value="general">général</option> <option value="travel">voyage</option> <option value="music">musique</option> </select> </label> <button onClick={() => setShow(!show)}> {show ? 'Fermer le salon' : 'Ouvrir le salon'} </button> {show && <hr />} {show && <ChatRoom roomId={roomId} />} </> ); }
Vous remarquerez que le nombre de connexions ouvertes ne cesse de grandir. Dans une véritable appli, ça causerait des problèmes de performances et de réseau. Le problème vient de l’absence de fonction de nettoyage dans votre Effet :
useEffect(() => {
const connection = createConnection(serverUrl, roomId);
connection.connect();
return () => connection.disconnect();
}, [roomId]);
Maintenant que votre Effet « fait le nettoyage » et supprime les connexions obsolètes, la fuite est réparée. Remarquez cependant que le problème n’est devenu visible qu’une fois de nouvelles fonctionnalités ajoutées (la liste déroulante).
Dans l’exemple original, le bug ne sautait pas aux yeux. Enrobez maintenant le code original (et buggué) dans un composant <StrictMode>
:
import { useState, useEffect } from 'react'; import { createConnection } from './chat.js'; const serverUrl = 'https://localhost:1234'; const roomId = 'general'; export default function ChatRoom() { useEffect(() => { const connection = createConnection(serverUrl, roomId); connection.connect(); }, []); <h1>Bienvenue sur le salon {roomId} !</h1>; }
Avec le mode strict, vous voyez immédiatement qu’il y a un problème (le nombre de connexions actives monte à 2). Ce mode exécute le cycle initialisation - nettoyage une fois de plus pour chaque Effet. Cet Effet n’a pas de logique de nettoyage, il crée donc une connexion supplémentaire sans jamais la détruire. C’est un indice qu’il vous manque une fonction de nettoyage.
Le mode strict vous permet de détecter de telles erreurs tôt dans le process. Lorsque vous corrigez votre Effet en ajoutant une fonction de nettoyage dans le mode strict, vous corrigez également de nombreux bugs potentiels en production, telle que la liste déroulante vue précédemment :
import { useState, useEffect } from 'react'; import { createConnection } from './chat.js'; const serverUrl = 'https://localhost:1234'; function ChatRoom({ roomId }) { useEffect(() => { const connection = createConnection(serverUrl, roomId); connection.connect(); return () => connection.disconnect(); }, [roomId]); <h1>Bienvenue sur le salon {roomId} !</h1>; } export default function App() { const [roomId, setRoomId] = useState('general'); const [show, setShow] = useState(false); return ( <> <label> Choisissez le salon :{' '} <select value={roomId} onChange={e => setRoomId(e.target.value)} > <option value="general">général</option> <option value="travel">voyage</option> <option value="music">musique</option> </select> </label> <button onClick={() => setShow(!show)}> {show ? 'Ouvrir le salon' : 'Fermer le salon'} </button> {show && <hr />} {show && <ChatRoom roomId={roomId} />} </> ); }
Remarquez que le nombre de connexions actives dans la console cesse de grandir maintenant.
Sans le mode strict, il était facile de passer à côté du fait que l’Effet nécessitait une fonction de nettoyage. En exécutant initialisation → nettoyage → initialisation plutôt que initialisation de votre Effet en développement, le mode strict a rendu l’absence de fonction de nettoyage plus visible.
Apprenez-en davantage sur l’implémentation de fonction de nettoyage des Effets.
Corriger les alertes de dépréciation activées par le mode strict
React alerte si certains composants quelque part à l’intérieur de l’arbre de <StrictMode>
utilisent l’une de ces API dépréciées :
findDOMNode
. Voir les alternatives.- Les méthodes de cycle de vie
UNSAFE_
des composants à base de classes, telles queUNSAFE_componentWillMount
. Voir les alternatives. - Les anciens contextes (
childContextTypes
,contextTypes
etgetChildContext
). Voir les alternatives. - Les anciennes refs textuelles (
this.refs
). Voir les alternatives.
Ces API sont avant tout utilisées dans les anciens composants à base de classes et n’apparaissent que rarement dans les applis modernes.