Component
est la classe de base pour les composants React définis à l’aide de classes JavaScript. Les composants à base de classes restent pris en charge par React, mais nous les déconseillons pour tout nouveau code.
class Greeting extends Component {
render() {
return <h1>Salut {this.props.name} !</h1>;
}
}
- Référence
Component
context
props
refs
state
constructor(props)
componentDidCatch(error, info)
componentDidMount()
componentDidUpdate(prevProps, prevState, snapshot?)
componentWillMount()
componentWillReceiveProps(nextProps)
componentWillUpdate(nextProps, nextState)
componentWillUnmount()
forceUpdate(callback?)
getChildContext()
getSnapshotBeforeUpdate(prevProps, prevState)
render()
setState(nextState, callback?)
shouldComponentUpdate(nextProps, nextState, nextContext)
UNSAFE_componentWillMount()
UNSAFE_componentWillReceiveProps(nextProps, nextContext)
UNSAFE_componentWillUpdate(nextProps, nextState)
static childContextTypes
static contextTypes
static contextType
static defaultProps
static propTypes
static getDerivedStateFromError(error)
static getDerivedStateFromProps(props, state)
- Utilisation
- Alternatives
Référence
Component
Pour définir un composant React sous forme de classe, étendez la classe Component
fournie par React et définissez sa méthode render
:
import { Component } from 'react';
class Greeting extends Component {
render() {
return <h1>Salut {this.props.name} !</h1>;
}
}
Seule la méthode render
est requise, les autres méthodes sont optionnelles.
Voir d’autres exemples ci-dessous.
context
Le contexte d’un composant à base de classe est mis à disposition dans this.context
. Il n’est disponible que si vous précisez quel contexte vous souhaitez récupérer en utilisant static contextType
(approche plus récente) ou static contextTypes
(approche dépréciée).
Un composant à base de classe ne peut lire qu’un contexte à la fois.
class Button extends Component {
static contextType = ThemeContext;
render() {
const theme = this.context;
const className = 'button-' + theme;
return (
<button className={className}>
{this.props.children}
</button>
);
}
}
props
Les props passées à un composant à base de classe sont mises à disposition dans this.props
.
class Greeting extends Component {
render() {
return <h1>Salut {this.props.name} !</h1>;
}
}
<Greeting name="Clara" />
refs
Vous permet d’accéder à des refs textuelles historiques pour ce composant.
state
L’état d’un composant à base de classe est mis à disposition dans this.state
. La champ state
doit être un objet. Ne modifiez pas l’état directement. Si vous souhaitez modifier l’état, appelez setState
avec un objet d’état en argument.
class Counter extends Component {
state = {
age: 31,
};
handleAgeChange = () => {
this.setState({
age: this.state.age + 1
});
};
render() {
return (
<>
<button onClick={this.handleAgeChange}>
Prendre de l’âge
</button>
<p>Vous avez {this.state.age} ans.</p>
</>
);
}
}
constructor(props)
Le constructeur est exécuté avant le montage (l’ajout dans le DOM) de votre composant. En général, vous n’utilisez un constructeur dans React que pour deux raisons. Il vous permet de déclarer votre état puis de lier certaines de vos méthodes à votre instance :
class Counter extends Component {
constructor(props) {
super(props);
this.state = { counter: 0 };
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
// ...
}
Si vous utilisez une syntaxe JavaScript moderne, vous aurez rarement besoin des constructeurs. Vous pouvez plutôt réécrire le code ci-dessus en utilisant des initialiseurs de champs d’instance qui sont pris en charge par tous les navigateurs modernes et par des outils comme Babel :
class Counter extends Component {
state = { counter: 0 };
handleClick = () => {
// ...
}
Un constructeur ne devrait contenir aucun effet de bord ni aucun abonnement.
Paramètres
props
: les props initiales du composant.
Valeur renvoyée
constructor
ne devrait rien renvoyer.
Limitations
-
Ne lancez aucun effet de bord et ne souscrivez aucun abonnement dans le constructeur. Utilisez plutôt
componentDidMount
pour ça. -
Dans un constructeur, vous devez impérativement appeler
super(props)
avant toute autre instruction. Si vous ne le faites pas,this.props
seraundefined
pendant l’exécution du constructeur, ce qui peut être déroutant et causer des bugs. -
Le constructeur est le seul endroit où vous pouvez affecter une valeur directement à
this.state
. Dans toutes les autres méthodes, vous devez plutôt utiliserthis.setState()
. En revanche, n’appelez passetState
dans le constructeur. -
Lorsque vous faites du rendu côté serveur, le constructeur sera exécuté côté serveur aussi, suivi de la méthode
render
. En revanche, les méthodes de cycle de vie telles quecomponentDidMount
oucomponentWillUnmount
ne seront pas exécutées côté serveur. -
En Mode Strict, React appellera votre
constructor
deux fois en développement, puis jettera une des instances obtenues. Ce comportement vous permet de repérer des effets de bord involontaires qui doivent être sortis duconstructor
.
componentDidCatch(error, info)
Si vous définissez componentDidCatch
, React l’appellera lorsqu’un composant descendant lèvera une erreur lors du rendu. Ça vous permettra de signaler l’erreur à un service de supervision en production.
Elle est en général utilisée conjointement avec static getDerivedStateFromError
, qui vous permet de mettre à jour l’état en réaction à une erreur afin d’afficher un message d’erreur à l’utilisateur. Un composant doté de ces méthodes est ce qu’on appelle un périmètre d’erreur.
Paramètres
-
error
: l’erreur qui a été levée. En pratique il s’agira généralement d’une instance d’Error
, mais ce n’est pas garanti parce que JavaScript autorise unthrow
de n’importe quelle valeur, y compris des chaînes de caractères et mêmenull
. -
info
: un objet contenant des informations complémentaires sur l’erreur. Son champcomponentStack
contient une pile d’appel de rendu avec le composant ayant levé l’erreur, ainsi que les noms et emplacements dans le code source de tous ses composants parents. En production, les noms des composants seront minifiés. Si vous mettez en place un signalement d’erreurs en production, vous pouvez décoder la pile d’appels de rendu grâce aux sourcemaps, exactement comme pour les piles d’appels d’erreurs JavaScript usuelles.
Valeur renvoyée
componentDidCatch
ne devrait rien renvoyer.
Limitations
-
Par le passé, on appelait couramment
setState
danscomponentDidCatch
pour mettre à jour l’UI et afficher un message d’erreur de remplacement. C’est déprécié en faveur d’une définition destatic getDerivedStateFromError
. -
Les builds de production et de développement diffèrent légèrement dans leur gestion de l’erreur par
componentDidCatch
. En développement, les erreurs se propageront jusqu’àwindow
, ce qui signifie quewindow.onerror
etwindow.addEventListener('error', callback)
intercepteront les erreurs attrapées parcomponentDidCatch
. En production, les erreurs ne seront pas propagées, de sorte que les gestionnaires d’erreurs placés plus haut dans l’arbre ne recevront que les erreurs qui n’auront pas été expressément interceptées parcomponentDidCatch
.
componentDidMount()
Si vous définissez la méthode componentDidMount
, React l’appellera lorsque votre composant sera ajouté au DOM (monté). C’est l’endroit classique pour démarrer un chargement de données, souscrire des abonnements, ou manipuler des nœuds du DOM.
Si vous implémentez componentDidMount
, vous aurez généralement besoin d’implémenter d’autres méthodes de cycle de vie pour éviter les bugs. Si par exemple componentDidMount
lit de l’état et des props, vous devrez aussi implémenter componentDidUpdate
pour en gérer les modifications, et componentWillUnmount
pour nettoyer toute mise en place effectuée par componentDidMount
.
class ChatRoom extends Component {
state = {
serverUrl: 'https://localhost:1234'
};
componentDidMount() {
this.setupConnection();
}
componentDidUpdate(prevProps, prevState) {
if (
this.props.roomId !== prevProps.roomId ||
this.state.serverUrl !== prevState.serverUrl
) {
this.destroyConnection();
this.setupConnection();
}
}
componentWillUnmount() {
this.destroyConnection();
}
// ...
}
Paramètres
componentDidMount
ne prend aucun paramètre.
Valeur renvoyée
componentDidMount
ne devrait rien renvoyer.
Limitations
-
En Mode Strict, en développement React appellera
componentDidMount
, puis appellera immédiatementcomponentWillUnmount
et rappelleracomponentDidMount
une seconde fois. Ça vous aide à remarquer un oubli d’implémentation decomponentWillUnmount
, ou un « miroir » insuffisant dans celle-ci de la logique présente danscomponentDidMount
. -
Même si vous pourriez appeler immédiatement
setState
danscomponentDidMount
, il est préférable de l’éviter autant que possible. Ça déclencherait un rendu supplémentaire, qui arriverait toutefois avant que le navigateur n’ait mis à jour l’affichage. Ça garantit que même si la méthoderender
est bien appelée deux fois dans un tel cas, l’utilisateur ne verra pas l’état intermédiaire. Utilisez cette approche avec précaution, parce qu’elle nuit aux performances. La plupart du temps, vous devriez pouvoir plutôt définir l’état initial dans leconstructor
. Ça reste toutefois utile pour des cas comme les boîtes de dialogue modales et les infobulles, qui nécessitent une mesure de nœud DOM avant de pouvoir afficher quelque chose qui dépend de leur taille ou de leur position.
componentDidUpdate(prevProps, prevState, snapshot?)
Si vous définissez la méthode componentDidUpdate
, React l’appellera immédiatement après que le composant a recalculé son rendu et mis à jour ses props et son état. Cette méthode n’est pas appelée lors du rendu initial.
Vous pouvez l’utiliser pour manipuler le DOM après une mise à jour. C’est également un endroit courant pour des requêtes réseau, du moment que vous comparez les nouvelles props aux anciennes (une requête réseau pourrait par exemple être superflue si les props n’ont pas bougé). En général, vous l’utiliserez conjointement à componentDidMount
et componentWillUnmount
:
class ChatRoom extends Component {
state = {
serverUrl: 'https://localhost:1234'
};
componentDidMount() {
this.setupConnection();
}
componentDidUpdate(prevProps, prevState) {
if (
this.props.roomId !== prevProps.roomId ||
this.state.serverUrl !== prevState.serverUrl
) {
this.destroyConnection();
this.setupConnection();
}
}
componentWillUnmount() {
this.destroyConnection();
}
// ...
}
Paramètres
-
prevProps
: les props de votre composant avant la mise à jour. ComparezprevProps
àthis.props
pour déterminer ce qui a changé. -
prevState
: l’état de votre composant avant la mise à jour. ComparezprevState
àthis.state
pour déterminer ce qui a changé. -
snapshot
: si vous avez implémentégetSnapshotBeforeUpdate
,snapshot
contiendra la valeur que vous aviez renvoyée depuis cette méthode. Dans les autres cas, ça vaudraundefined
.
Valeur renvoyée
componentDidUpdate
ne devrait rien renvoyer.
Limitations
-
componentDidUpdate
ne sera pas appelée sishouldComponentUpdate
est définie et renvoiefalse
. -
La logique dans
componentDidUpdate
devrait généralement être entourée de conditions comparantthis.props
etprevProps
, ainsi quethis.state
etprevState
. Faute de quoi vous risquez des boucles de rendu infinies. -
Même si vous pourriez appeler immédiatement
setState
danscomponentDidMount
, il est préférable de l’éviter autant que possible. Ça déclencherait un rendu supplémentaire, qui arriverait toutefois avant que le navigateur n’ait mis à jour l’affichage. Ça garantit que même si la méthoderender
est bien appelée deux fois dans un tel cas, l’utilisateur ne verra pas l’état intermédiaire. Cette approche peut nuire aux performances, mais reste toutefois utile pour des cas comme les boîtes de dialogue modales et les infobulles, qui nécessitent une mesure de nœud DOM avant de pouvoir afficher quelque chose qui dépend de leur taille ou de leur position.
componentWillMount()
componentWillReceiveProps(nextProps)
componentWillUpdate(nextProps, nextState)
componentWillUnmount()
Si vous définissez la méthode componentWillUnmount
, React l’appellera avant que votre composant soit retiré du DOM (démonté). C’est un endroit courant pour annuler les chargements de données et vous désabonner.
La logique dans componentWillUnmount
devrait agir « en miroir » de celle dans componentDidMount
. Si par exemple componentDidMount
souscrit un abonnement, componentWillUnmount
devrait faire le désabonnement associé. Si la logique de nettoyage dans votre componentWillUnmount
lit des props ou de l’état, vous aurez généralement besoin d’implémenter également componentDidUpdate
pour nettoyer les ressources (tels que les abonnements) correspondant aux anciennes props et anciens états.
class ChatRoom extends Component {
state = {
serverUrl: 'https://localhost:1234'
};
componentDidMount() {
this.setupConnection();
}
componentDidUpdate(prevProps, prevState) {
if (
this.props.roomId !== prevProps.roomId ||
this.state.serverUrl !== prevState.serverUrl
) {
this.destroyConnection();
this.setupConnection();
}
}
componentWillUnmount() {
this.destroyConnection();
}
// ...
}
Paramètres
componentWillUnmount
ne prend aucun paramètre.
Valeur renvoyée
componentWillUnmount
ne devrait rien renvoyer.
Limitations
- En Mode Strict, en développement React appellera
componentDidMount
, puis appellera immédiatementcomponentWillUnmount
et rappelleracomponentDidMount
une seconde fois. Ça vous aide à remarquer un oubli d’implémentation decomponentWillUnmount
, ou un « miroir » insuffisant dans celle-ci de la logique présente danscomponentDidMount
.
forceUpdate(callback?)
Force un composant à recalculer son rendu.
Vous n’en avez normalement pas besoin. Si la méthode render
de votre composant se contente de lire this.props
, this.state
ou this.context
, il refera automatiquement son rendu lorsque vous appelez setState
dans votre composant ou dans un de ses parents. En revanche, si la méthode render
de votre composant lit directement une source de données extérieure, vous devrez demander à React de mettre à jour l’interface utilisateur lorsque cette source de données change. C’est ce à quoi sert forceUpdate
.
Essayez d’éviter tout utilisation de forceUpdate
, en ne lisant que this.props
et this.state
dans render
.
Paramètres
callback
optionnel : s’il est précisé, React appellera lecallback
que vous avez fourni une fois la mise à jour retranscrite dans le DOM.
Valeur renvoyée
forceUpdate
ne renvoie rien.
Limitations
- Si vous appelez
forceUpdate
, React recalculera le rendu sans appeler d’abordshouldComponentUpdate
.
getChildContext()
Vous permet de spécifier les valeurs fournies par le composant pour les contextes historiques.
getSnapshotBeforeUpdate(prevProps, prevState)
Si vous implémentez getSnapshotBeforeUpdate
, React l’appellera juste avant de mettre à jour le DOM. Ça permet à votre composant de capturer certaines informations issues du DOM (telles que la position de défilement) avant qu’elles risquent d’évoluer. Toute valeur renvoyée par cette méthode de cycle de vie sera passée en paramètre à componentDidUpdate
.
Vous pouvez par exemple l’utiliser dans une UI de type fil de discussion qui aurait besoin de préserver la position de défilement lors des mises à jour :
class ScrollingList extends React.Component {
constructor(props) {
super(props);
this.listRef = React.createRef();
}
getSnapshotBeforeUpdate(prevProps, prevState) {
// Ajoute-t-on des nouveaux éléments à la liste ?
// Capturons alors la position de défilement pour l’ajuster
// par la suite.
if (prevProps.list.length < this.props.list.length) {
const list = this.listRef.current;
return list.scrollHeight - list.scrollTop;
}
return null;
}
componentDidUpdate(prevProps, prevState, snapshot) {
// Si nous avons une valeur capturée, c’est qu’on a ajouté
// de nouveaux éléments. On ajuste alors le défilement de façon
// à ce que les nouveaux éléments ne décalent pas les anciens
// hors de la zone visible.
// (Ici `snapshot` est la valeur renvoyée `getSnapshotBeforeUpdate`.)
if (snapshot !== null) {
const list = this.listRef.current;
list.scrollTop = list.scrollHeight - snapshot;
}
}
render() {
return (
<div ref={this.listRef}>{/* ...contenu... */}</div>
);
}
}
Dans l’exemple ci-dessus, il est vital de lire la propriété scrollHeight
directement dans getSnapshotBeforeUpdate
. On ne pourrait pas la lire de façon fiable dans render
, UNSAFE_componentWillReceiveProps
ou UNSAFE_componentWillUpdate
parce qu’il existe un risque de décalage temporel entre les appels de ces méthodes et la mise à jour du DOM par React.
Paramètres
-
prevProps
: les props de votre composant avant la mise à jour. ComparezprevProps
àthis.props
pour déterminer ce qui a changé. -
prevState
: l’état de votre composant avant la mise à jour. ComparezprevState
àthis.state
pour déterminer ce qui a changé.
Valeur renvoyée
Vous devriez renvoyer une valeur capturée de quelque type que ce soit, voire null
. La valeur que vous renvoyez sera passée en troisième argument à componentDidUpdate
.
Limitations
getSnapshotBeforeUpdate
ne sera pas appelée sishouldComponentUpdate
est définie et renvoiefalse
.
render()
La méthode render
est la seule méthode obligatoire dans un composant à base de classe.
La méthode render
devrait spécifier ce que vous souhaitez afficher à l’écran, par exemple :
import { Component } from 'react';
class Greeting extends Component {
render() {
return <h1>Salut {this.props.name} !</h1>;
}
}
React est susceptible d’appeler render
à tout moment, aussi vous ne devriez pas supposer son exécution à un moment particulier. En général, la méthode render
devrait renvoyer un contenu JSX, mais certains autres types de résultats (comme les chaînes de caractères) sont autorisés. Pour calculer le JSX renvoyé, la méthode render
peut lire this.props
, this.state
et this.context
.
Vous devriez écrire la méthode render
sous forme de fonction pure, c’est-à-dire qu’elle devrait toujours renvoyer le même résultat si les props, l’état et le contexte n’ont pas changé. Elle ne devrait par ailleurs pas contenir d’effets de bord (tels que des souscriptions d’abonnements) ou interagir avec des API du navigateur. Les effets de bord sont censés survenir soit dans des gestionnaires d’événements, soit dans des méthodes commecomponentDidMount
.
Paramètres
render
ne prend aucun paramètre.
Valeur renvoyée
render
peut renvoyer n’importe quel nœud React valide. Ça inclut les éléments React tels que <div />
, les chaînes de caractères, les nombres, les portails, les nœuds vides (null
, undefined
, true
et false
) et les tableaux de nœuds React.
Limitations
-
render
devrait être écrite comme une fonction pure des props, de l’état et du contexte. Elle ne devrait comporter aucun effet de bord. -
render
ne sera pas appelée sishouldComponentUpdate
est définie et renvoiefalse
.
- En Mode Strict, React appellera
render
deux fois en développement et jettera un des résultats. Ça vous permet de repérer des effets de bord involontaires qui doivent être sortis derender
.
- Il n’y a pas de correspondance directe entre l’appel à
render
et les appels ultérieurs àcomponentDidMount
etcomponentDidUpdate
. Certains résultats d’appels àrender
sont susceptibles d’être ignorés par React lorsque ça présente un avantage.
setState(nextState, callback?)
Appelez setState
pour mettre à jour l’état de votre composant React.
class Form extends Component {
state = {
name: 'Clara',
};
handleNameChange = (e) => {
const newName = e.target.value;
this.setState({
name: newName
});
}
render() {
return (
<>
<input value={this.state.name} onChange={this.handleNameChange} />
<p>Salut {this.state.name}.</p>
</>
);
}
}
setState
maintient une file d’attente de modifications à apporter à l’état du composant. Elle indique à React que ce composant et ses enfants doivent recalculer leur rendu avec un nouvel état. C’est le principal moyen de mettre à jour l’interface utilisateur suite à des interactions.
Vous pouvez aussi passer une fonction à setState
. Ça vous permet de mettre à jour l’état sur base de sa valeur précédente :
handleIncreaseAge = () => {
this.setState(prevState => {
return {
age: prevState.age + 1
};
});
}
Vous n’êtes pas obligé·e de faire ça, mais c’est pratique lorsque vous souhaitez accumuler plusieurs mises à jour de l’état au sein d’un même événement.
Paramètres
-
nextState
: soit un objet, soit une fonction.- Si vous passez un objet comme
nextState
, il sera superficiellement fusionné dansthis.state
. - Si vous passez une fonction comme
nextState
, elle sera traitée comme une fonction de mise à jour. Elle doit être pure, doit accepter l’état en attente et les props comme arguments, et doit renvoyer un objet qui sera superficiellement fusionné dansthis.state
. React placera votre fonction de mise à jour dans une file d’attente puis refera le rendu de votre composant. Lors du prochain rendu, React calculera le prochain état en appliquant successivement toutes les fonctions de mise à jour en attente, en partant de l’état précédent.
- Si vous passez un objet comme
-
callback
optionnel : s’il est précisé, React appellera lecallback
que vous avez fourni une fois la mise à jour retranscrite dans le DOM.
Valeur renvoyée
setState
ne renvoie rien.
Limitations
-
Pensez à
setState
comme à une requête plutôt qu’une commande de mise à jour immédiate du composant. Lorsque plusieurs composants mettent à jour leurs états en réaction à un événement, React regroupe leurs mises à jour et refait leurs rendus en une unique passe, à la fin de l’événement. Pour les rares cas où vous auriez besoin de forcer une mise à jour d’état spécifique à être appliquée de façon synchrone, vous pourriez l’enrober dansflushSync
, mais ça gâche généralement la performance. -
setState
ne met pas immédiatement à jourthis.state
. Il est donc piégeux de lirethis.state
juste après avoir appelésetState
. Utilisez plutôtcomponentDidUpdate
ou l’argumentcallback
desetState
, qui vous garantissent tous les deux une exécution après que la mise à jour a été appliquée. Si vous avez besoin de mettre à jour l’état sur base de l’état précédent, vous pouvez passer une fonction pournextState
, comme décrit plus haut.
shouldComponentUpdate(nextProps, nextState, nextContext)
Si vous définissez shouldComponentUpdate
, React l’appellera pour déterminer s’il peut éviter de calculer un nouveau rendu.
Si vous êtes certain·e de vouloir écrire ça vous-même, vous pouvez comparer this.props
avec nextProps
et this.state
avec nextState
et renvoyer false
pour indiquer à React que le recalcul du rendu peut être sauté.
class Rectangle extends Component {
state = {
isHovered: false
};
shouldComponentUpdate(nextProps, nextState) {
if (
nextProps.position.x === this.props.position.x &&
nextProps.position.y === this.props.position.y &&
nextProps.size.width === this.props.size.width &&
nextProps.size.height === this.props.size.height &&
nextState.isHovered === this.state.isHovered
) {
// Rien n’a changé, un nouveau rendu est donc superflu
return false;
}
return true;
}
// ...
}
React appelle shouldComponentUpdate
avant de refaire le rendu lorsque des nouvelles props ou un nouvel état sont fournis. Ça renvoie par défaut true
. Cette méthode n’est pas appelée pour le rendu initial, ni lorsque forceUpdate
est utilisée.
Paramètres
nextProps
: les prochaines props pour le rendu à venir. CompareznextProps
àthis.props
pour déterminer ce qui a changé.nextState
: le prochain état pour le rendu à venir. CompareznextState
àthis.state
pour déterminer ce qui a changé.nextContext
: le prochain contexte pour le rendu à venir. CompareznextContext
àthis.context
pour déterminer ce qui a changé. N’est disponible que si vous avez spécifiéstatic contextType
(approche plus récente) oustatic contextTypes
(approche dépréciée).
Valeur renvoyée
Renvoie true
si vous souhaitez que le composant refasse son rendu. C’est le comportement par défaut.
Renvoie false
pour indiquer à React de sauter le recalcul du rendu.
Limitations
-
Cette méthode existe seulement comme une optimisation des performances. Si votre composant ne fonctionne pas sans elle, corrigez-le d’abord.
-
Envisagez de recourir à
PureComponent
plutôt que d’écrireshouldComponentUpdate
à la main.PureComponent
fait une comparaison superficielle des props et de l’état, et réduit le risque de sauter une mise à jour utile. -
Nous vous déconseillons de faire des comparaisons profondes ou d’utiliser
JSON.stringify
dansshouldComponentUpdate
. Ça rend la performance imprévisible et dépendante des structures de données de chaque prop et élément d’état. Au meilleur des cas, vous risquez d’introduire des gels de plusieurs secondes dans votre appli, au pire cas de la faire carrément planter. -
Renvoyer
false
n’empêche pas vos composants enfants de refaire leurs calculs si leurs données changent. -
Renvoyer
false
ne garantit pas que le composant sautera son rendu. React se servira de votre valeur renvoyée comme d’un conseil, mais reste susceptible d’opter pour un recalcul du rendu si ça lui semble par ailleurs justifié.
UNSAFE_componentWillMount()
Si vous définissez UNSAFE_componentWillMount
, React l’appellera immédiatement après le constructor
. Cette méthode n’existe plus que pour des raisons historiques et ne devrait pas être utilisée dans du nouveau code. Utilisez plutôt l’une de ces alternatives :
- Pour initialiser l’état, déclarez un champ d’instance
state
ou affectezthis.state
dans leconstructor
. - Si vous avez besoin d’exécuter un effet de bord ou de souscrire un abonnement, déplacez plutôt cette logique dans
componentDidMount
.
Consultez des exemples de migration des méthodes historiques de cycle de vie.
Paramètres
UNSAFE_componentWillMount
ne prend aucun paramètre.
Valeur renvoyée
UNSAFE_componentWillMount
ne devrait rien renvoyer.
Limitations
-
UNSAFE_componentWillMount
ne sera pas appelée si le composant implémentestatic getDerivedStateFromProps
ougetSnapshotBeforeUpdate
. -
En dépit de son nom,
UNSAFE_componentWillMount
ne garantit pas que le composant sera effectivement monté si votre appli utilise des fonctionnalités modernes de React telles queSuspense
. Si une tentative de rendu suspend (en raison par exemple d’un code de composant enfant qui ne serait pas encore chargé), React jettera l’arborescence en cours et essaiera de reconstruire le composant de zéro lors de la prochaine tentative. C’est pourquoi cette méthode n’est « pas fiable » (“unsafe”, NdT). Tout code qui se base sur le montage (comme la souscription d’un abonnement) devrait être placé danscomponentDidMount
. -
UNSAFE_componentWillMount
est la seule méthode de cycle de vie qui est exécutée lors d’un rendu côté serveur. Son déclenchement est en pratique identique à celui deconstructor
, vous devriez donc plutôt utiliserconstructor
pour ce type de logique.
UNSAFE_componentWillReceiveProps(nextProps, nextContext)
Si vous définissez UNSAFE_componentWillReceiveProps
, React l’appellera lorsque le composant recevra des nouvelles props. Cette méthode n’existe plus que pour des raisons historiques et ne devrait pas être utilisée dans du nouveau code. Utilisez plutôt l’une de ces alternatives :
- Si vous avez besoin d’exécuter un effet de bord (par exemple charger des données, dérouler une animation ou réinitialiser un abonnement) en réaction à des changements de props, déplacez plutôt cette logique dans
componentDidUpdate
. - Si vous souhaitez ne recalculer certaines données que lorsque certaines props changent, utilisez plutôt un utilitaire de mémoïsation.
- Si vous essayez de « réinitialiser » tout l’état quand une prop change, envisagez de plutôt faire un composant soit pleinement contrôlé soit pleinement non contrôlé mais avec une clé.
- Si vous avez besoin « d’ajuster » une partie de l’état quand une prop change, voyez si vous ne pouvez pas plutôt calculer toutes les infos nécessaires à partir des props seules lors du rendu. Si ce n’est pas possible, préférez
static getDerivedStateFromProps
.
Consultez des exemples de migration des méthodes historiques de cycle de vie.
Paramètres
nextProps
: les prochaines props que le composant va recevoir de son composant parent. CompareznextProps
àthis.props
pour déterminer ce qui a changé.nextContext
: le prochain contexte que le composant va recevoir de son plus proche fournisseur de contexte. CompareznextContext
àthis.context
pour déterminer ce qui a changé. N’est disponible que si vous avez par ailleurs spécifiéstatic contextType
(approche plus récente) oustatic contextTypes
(approche dépréciée).
Valeur renvoyée
UNSAFE_componentWillReceiveProps
ne devrait rien renvoyer.
Limitations
-
UNSAFE_componentWillReceiveProps
ne sera pas appelée si le composant implémentestatic getDerivedStateFromProps
ougetSnapshotBeforeUpdate
. -
En dépit de son nom,
UNSAFE_componentWillReceiveProps
ne garantit pas que le composant recevra effectivement ces props si votre appli utilise des fonctionnalités modernes de React telles queSuspense
. Si une tentative de rendu suspend (en raison par exemple d’un code de composant enfant qui ne serait pas encore chargé), React jettera l’arborescence en cours et essaiera de reconstruire le composant de zéro lors de la prochaine tentative. D’ici là, les props pourraient avoir encore changé. C’est pourquoi cette méthode n’est « pas fiable » (“unsafe”, NdT). Tout code qui ne devrait être exécuté que pour des mises à jour confirmées (comme la réinitialisation d’un abonnement) devrait être placé danscomponentDidUpdate
. -
UNSAFE_componentWillReceiveProps
n’implique pas que le composant recevra des props différentes de la fois précédente. Vous devez comparernextProps
avecthis.props
vous-même pour vérifier que quelque chose a changé. -
React n’appelle pas
UNSAFE_componentWillReceiveProps
avec les props initiales lors du montage. Il n’appelle cette méthode que si tout ou partie des props du composant vont être mises à jour. Par exemple, un appel àsetState
ne déclenche généralement pasUNSAFE_componentWillReceiveProps
au sein du même composant.
UNSAFE_componentWillUpdate(nextProps, nextState)
Si vous définissez UNSAFE_componentWillUpdate
, React l’appellera avant de refaire un rendu avec les nouvelles props et le nouvel état. Cette méthode n’existe plus que pour des raisons historiques et ne devrait pas être utilisée dans du nouveau code. Utilisez plutôt l’une de ces alternatives :
- Si vous avez besoin d’exécuter un effet de bord (par exemple charger des données, dérouler une animation ou réinitialiser un abonnement) en réaction à des changements de props ou d’état, déplacez plutôt cette logique dans
componentDidUpdate
. - Si vous avez besoin de lire des informations depuis le DOM (par exemple la position de défilement) pour l’utiliser ensuite dans
componentDidUpdate
, lisez-la plutôt dansgetSnapshotBeforeUpdate
.
Consultez des exemples de migration des méthodes historiques de cycle de vie.
Paramètres
nextProps
: les prochaines props de votre composant pour le rendu à venir. CompareznextProps
àthis.props
pour déterminer ce qui a changé.nextState
: le prochain état de votre composant pour le rendu à venir. CompareznextState
àthis.state
pour déterminer ce qui a changé.
Valeur renvoyée
UNSAFE_componentWillUpdate
ne devrait rien renvoyer.
Limitations
-
UNSAFE_componentWillUpdate
ne sera pas appelée sishouldComponentUpdate
est définie et renvoiefalse
. -
UNSAFE_componentWillUpdate
ne sera pas appelée si le composant implémentestatic getDerivedStateFromProps
ougetSnapshotBeforeUpdate
. -
Il est interdit d’appeler
setState
(ou toute méthode entraînant un appel àsetState
, tel que le dispatch d’une action Redux) au sein decomponentWillUpdate
. -
En dépit de son nom,
UNSAFE_componentWillUpdate
ne garantit pas que le composant sera effectivement mis à jour si votre appli utilise des fonctionnalités modernes de React telles queSuspense
. Si une tentative de rendu suspend (en raison par exemple d’un code de composant enfant qui ne serait pas encore chargé), React jettera l’arborescence en cours et essaiera de reconstruire le composant de zéro lors de la prochaine tentative. D’ici là, les props ou l’état pourraient avoir encore changé. C’est pourquoi cette méthode n’est « pas fiable » (“unsafe”, NdT). Tout code qui ne devrait être exécuté que pour des mises à jour confirmées (comme la réinitialisation d’un abonnement) devrait être placé danscomponentDidUpdate
. -
UNSAFE_componentWillUpdate
n’implique pas que le composant recevra des props ou un état différents de la fois précédente. Vous devez comparer vous-mêmenextProps
avecthis.props
etnextState
avecthis.state
pour vérifier que quelque chose a changé. -
React n’appellera pas
UNSAFE_componentWillUpdate
avec les props et état initiaux lors du montage.
static childContextTypes
Vous permet de spécifier quel contexte historique est fourni par ce composant.
static contextTypes
Vous permet de spécifier quel contexte historique est consommé par ce composant.
static contextType
Si vous souhaitez lire this.context
dans votre composant à base de classe, vous devez spécifier le contexte que vous souhaitez lire. Le contexte que vous spécifiez comme static contextType
doit être une valeur créée auparavant parcreateContext
.
class Button extends Component {
static contextType = ThemeContext;
render() {
const theme = this.context;
const className = 'button-' + theme;
return (
<button className={className}>
{this.props.children}
</button>
);
}
}
static defaultProps
Vous pouvez définir static defaultProps
pour fournir des valeurs par défaut aux props de la classe. Elles seront utilisées pour les props manquantes ou valant undefined
, mais pas pour les props valant null
.
Voici par exemple comment définir une prop color
qui devrait valoir 'blue'
par défaut :
class Button extends Component {
static defaultProps = {
color: 'blue'
};
render() {
return <button className={this.props.color}>Cliquez ici</button>;
}
}
Si la prop color
n’est pas fournie ou est à undefined
, elle sera mise par défaut à 'blue'
:
<>
{/* this.props.color vaudra "blue" */}
<Button />
{/* this.props.color vaudra "blue" */}
<Button color={undefined} />
{/* this.props.color vaudra null */}
<Button color={null} />
{/* this.props.color vaudra "red" */}
<Button color="red" />
</>
static propTypes
Vous pouvez définir static propTypes
en utilisant le moduleprop-types
pour déclarer les types des props acceptées par votre composant. Ces types seront vérifiés lors du rendu en développement uniquement.
import PropTypes from 'prop-types';
class Greeting extends React.Component {
static propTypes = {
name: PropTypes.string
};
render() {
return (
<h1>Salut {this.props.name}</h1>
);
}
}
static getDerivedStateFromError(error)
Si vous définissez static getDerivedStateFromError
, React l’appellera lorsqu’un composant descendant lèvera une erreur pendant le rendu. Ça vous permet d’afficher un message d’erreur plutôt que d’aboutir à une UI vide.
Elle est en général utilisée conjointement avec componentDidCatch
, qui vous permet par exemple d’envoyer un rapport d’erreur à un service de supervision. Un composant doté de ces méthodes est ce qu’on appelle un périmètre d’erreur.
Paramètres
error
: l’erreur qui a été levée. En pratique il s’agira généralement d’une instance d’Error
, mais ce n’est pas garanti parce que JavaScript autorise unthrow
de n’importe quelle valeur, y compris des chaînes de caractères et mêmenull
.
Valeur renvoyée
static getDerivedStateFromError
devrait renvoyer un objet d’état indiquant au composant d’afficher un message d’erreur.
Limitations
static getDerivedStateFromError
devrait être une fonction pure. Si vous souhaiter exécuter un effet de bord (comme par exemple un signalement à un service de supervision), vous devez aussi implémenter la méthodecomponentDidCatch
.
static getDerivedStateFromProps(props, state)
Si vous définissez static getDerivedStateFromProps
, React l’appellera juste avant d’appeler render
, tant au montage initial que lors des mises à jour ultérieures. Elle devrait renvoyer un objet de mise à jour de l’état, ou null
pour ne faire aucune mise à jour.
Cette méthode existe pour les rares cas d’usage où l’état dépend de changements de props au fil du temps. Par exemple, le composant Form
ci-dessous réinitialise son état email
lorsque la prop userID
change :
class Form extends Component {
state = {
email: this.props.defaultEmail,
prevUserID: this.props.userID
};
static getDerivedStateFromProps(props, state) {
// Dès que l’utilisateur actif change, réinitialise
// les parties de l’état liées à cet utilisateur.
// Dans cet exemple simple, il s’agit juste de l’e-mail.
if (props.userID !== state.prevUserID) {
return {
prevUserID: props.userID,
email: props.defaultEmail
};
}
return null;
}
// ...
}
Remarquez que cette approche requiert la conservation de la valeur précédente de la prop (comme userID
) dans l’état (comme ici prevUserID
).
Paramètres
props
: les prochaines props pour le rendu à venir.state
: le prochain état pour le rendu à venir.
Valeur renvoyée
static getDerivedStateFromProps
renvoie un objet utilisé pour mettre à jour l’état, ou null
pour ne rien mettre à jour.
Limitations
-
Cette méthode est déclenchée à chaque rendu, peu en importe la raison. Ce n’est pas comme
UNSAFE_componentWillReceiveProps
, qui elle ne serait déclenchée que lorsque le parent entraîne un nouveau rendu, mais pas suite à unsetState
local. -
Cette méthode n’a pas accès à l’instance du composant. Si vous le souhaitez, vous pouvez réutiliser du code entre
static getDerivedStateFromProps
et les autres méthodes de la classe en extrayant des fonctions pures basées sur les props et l’état du composant, que vous placeriez hors de la définition de la classe.
Utilisation
Définir un composant à base de classe
Pour définir un composant React sous forme de classe, étendez la classe Component
fournie par React et définissez sa méthode render
:
import { Component } from 'react';
class Greeting extends Component {
render() {
return <h1>Salut {this.props.name} !</h1>;
}
}
React appellera votre méthode render
dès qu’il doit déterminer quoi afficher à l’écran. Vous y renverrez en général du JSX. Votre méthode render
devrait être une fonction pure : elle devrait se limiter à calculer le JSX.
Tout comme les fonctions composants, un composant à base de classe peut recevoir des informations via ses props depuis son composant parent. En revanche, la syntaxe de consultation des props est différente. Si par exemple le composant parent fait le rendu de <Greeting name="Clara" />
, vous pourrez lire la prop name
depuis this.props
, en utilisant this.props.name
:
import { Component } from 'react'; class Greeting extends Component { render() { return <h1>Salut {this.props.name} !</h1>; } } export default function App() { return ( <> <Greeting name="Laure" /> <Greeting name="Marie" /> <Greeting name="Nina" /> </> ); }
Remarquez que les Hooks (des fonctions dont le nom commence par use
, telles que useState
) ne sont pas pris en charge par les composants à base de classes.
Ajouter de l’état à un composant à base de classe
Pour ajouter un état à une classe, affectez un objet à la propriété state
. Pour mettre à jour l’état, appelez this.setState
.
import { Component } from 'react'; export default class Counter extends Component { state = { name: 'Clara', age: 31, }; handleNameChange = (e) => { this.setState({ name: e.target.value }); } handleAgeChange = () => { this.setState({ age: this.state.age + 1 }); }; render() { return ( <> <input value={this.state.name} onChange={this.handleNameChange} /> <button onClick={this.handleAgeChange}> Prendre de l’âge </button> <p>Salut {this.state.name}. Vous avez {this.state.age} ans.</p> </> ); } }
Ajouter des méthodes de cycle de vie à un composant à base de classe
Il existe plusieurs méthodes spéciales que vous pouvez définir sur votre classe.
Si vous définissez la méthode componentDidMount
, React l’appellera quand votre composant aura été ajouté au DOM (monté). React appellera componentDidUpdate
après que votre composant aura refait son rendu en raison de props ou d’un état modifiés. React appellera componentWillUnmount
juste avant que votre composant ne soit retiré du DOM (démonté).
Si vous implémentez componentDidMount
, vous aurez généralement besoin d’implémenter ces trois méthodes de cycle de vie pour éviter les bugs. Si par exemple componentDidMount
lit un état ou des props, vous devrez également implémenter componentDidUpdate
pour en gérer les évolutions, ainsi que componentWillUnmount
pour nettoyer toute mise en place effectuée dans componentDidMount
.
Par exemple, ce composant ChatRoom
conserve une connexion au salon de discussion synchronisée avec les props et l’état :
import { Component } from 'react'; import { createConnection } from './chat.js'; export default class ChatRoom extends Component { state = { serverUrl: 'https://localhost:1234' }; componentDidMount() { this.setupConnection(); } componentDidUpdate(prevProps, prevState) { if ( this.props.roomId !== prevProps.roomId || this.state.serverUrl !== prevState.serverUrl ) { this.destroyConnection(); this.setupConnection(); } } componentWillUnmount() { this.destroyConnection(); } setupConnection() { this.connection = createConnection( this.state.serverUrl, this.props.roomId ); this.connection.connect(); } destroyConnection() { this.connection.disconnect(); this.connection = null; } render() { return ( <> <label> URL du serveur :{' '} <input value={this.state.serverUrl} onChange={e => { this.setState({ serverUrl: e.target.value }); }} /> </label> <h1>Bienvenue dans le salon {this.props.roomId} !</h1> </> ); } }
Remarquez qu’en développement et lorsque le Mode Strict est actif, React appellera componentDidMount
, puis appellera immédiatement componentWillUnmount
et rappellera componentDidMount
une seconde fois. Ça vous aide à remarquer un oubli d’implémentation de componentWillUnmount
, ou un « miroir » insuffisant dans celle-ci de la logique de componentDidMount
.
Capturer les erreurs de rendu avec un périmètre d’erreur
Par défaut, si votre application lève une erreur lors du rendu, React retirera son UI de l’écran. Pour éviter ça, vous pouvez enrober tout ou partie de votre UI dans un périmètre d’erreur. Un périmètre d’erreur est un composant spécial qui vous permet d’afficher une UI de secours plutôt que la partie plantée : un message d’erreur par exemple.
Pour implémenter un composant de périmètre d’erreur, vous devez fournir static getDerivedStateFromError
qui vous permet de mettre à jour votre état en réaction à une erreur afin d’afficher un message à l’utilisateur. Vous pouvez aussi, optionnellement, implémenter componentDidCatch
pour ajouter de la logique supplémentaire, comme par exemple un signalement de l’erreur à un service de supervision.
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
// Met à jour l'état pour que le prochain rendu affiche une
// UI de secours.
return { hasError: true };
}
componentDidCatch(error, info) {
// Exemple de "componentStack" :
// in ComponentThatThrows (created by App)
// in ErrorBoundary (created by App)
// in div (created by App)
// in App
logErrorToMyService(error, info.componentStack);
}
render() {
if (this.state.hasError) {
// Vous pouvez afficher n’importe quelle UI de secours
return this.props.fallback;
}
return this.props.children;
}
}
Vous pouvez alors enrober une partie de votre arbre de composants avec le périmètre :
<ErrorBoundary fallback={<p>Ça sent le pâté…</p>}>
<Profile />
</ErrorBoundary>
Si Profile
ou un de ses composants descendants lève une erreur, ErrorBoundary
« attrapera » cette erreur, affichera une UI de secours avec le message d’erreur fourni, et enverra un signalement de l’erreur de production à votre service de supervision.
Vous n’avez pas besoin d’enrober chaque composant dans son propre périmètre d’erreur. Lorsque vous réfléchissez à la granularité de vos périmètres d’erreurs, pensez aux emplacements logiques pour des messages d’erreurs. Dans une appli de messagerie par exemple, un périmètre d’erreur naturel se situerait autour de la liste des conversations. Il serait également envisageable de placer un périmètre autour de chaque message individuel. En revanche, ça ne servirait à rien d’en placer un autour de chaque avatar.
Alternatives
Migrer un composant simple d’une classe vers une fonction
Généralement, vous définirez plutôt vos composants sous forme de fonctions.
Supposons par exemple que vous souhaitiez convertir ce composant à base de classe Greeting
en une fonction composant :
import { Component } from 'react'; class Greeting extends Component { render() { return <h1>Salut {this.props.name} !</h1>; } } export default function App() { return ( <> <Greeting name="Laure" /> <Greeting name="Marie" /> <Greeting name="Nina" /> </> ); }
Définissez pour commencer une fonction nommée Greeting
. C’est là que vous allez déplacer le corps de votre méthode render
:
function Greeting() {
// ... déplacez ici le code de votre méthode `render` ...
}
Plutôt que de lire this.props.name
, définissez une prop name
au moyen d’une déstructuration dans la signature et lisez-la directement :
function Greeting({ name }) {
return <h1>Salut {name} !</h1>;
}
Voici l’exemple complet :
function Greeting({ name }) { return <h1>Salut {name} !</h1>; } export default function App() { return ( <> <Greeting name="Laure" /> <Greeting name="Marie" /> <Greeting name="Nina" /> </> ); }
Migrer un composant avec état d’une classe vers une fonction
Supposons que vous convertissiez ce composant à base de classe Counter
vers une fonction :
import { Component } from 'react'; export default class Counter extends Component { state = { name: 'Clara', age: 31, }; handleNameChange = (e) => { this.setState({ name: e.target.value }); } handleAgeChange = (e) => { this.setState({ age: this.state.age + 1 }); }; render() { return ( <> <input value={this.state.name} onChange={this.handleNameChange} /> <button onClick={this.handleAgeChange}> Prendre de l’âge </button> <p>Salut {this.state.name}. Vous avez {this.state.age} ans.</p> </> ); } }
Commencez par déclarer une fonction avec les variables d’état nécessaires :
import { useState } from 'react';
function Counter() {
const [name, setName] = useState('Clara');
const [age, setAge] = useState(42);
// ...
Convertissez ensuite les gestionnaires d’événements :
function Counter() {
const [name, setName] = useState('Clara');
const [age, setAge] = useState(42);
function handleNameChange(e) {
setName(e.target.value);
}
function handleAgeChange() {
setAge(age + 1);
}
// ...
Pour finir, remplacez toutes les références qui démarrent par this
avec les variables et fonctions définies dans votre composant. Remplacez par exemple this.state.age
par age
et this.handleNameChange
par handleNameChange
.
Voici le composant pleinement converti :
import { useState } from 'react'; export default function Counter() { const [name, setName] = useState('Clara'); const [age, setAge] = useState(42); function handleNameChange(e) { setName(e.target.value); } function handleAgeChange() { setAge(age + 1); } return ( <> <input value={name} onChange={handleNameChange} /> <button onClick={handleAgeChange}> Prendre de l’âge </button> <p>Salut {name}. You are {age}.</p> </> ) }
Migrer un composant doté de méthodes de cycle de vie d’une classe vers une fonction
Supposons que vous convertissiez ce composant à base de classe ChatRoom
, doté de méthodes de cycle de vie, vers une fonction :
import { Component } from 'react'; import { createConnection } from './chat.js'; export default class ChatRoom extends Component { state = { serverUrl: 'https://localhost:1234' }; componentDidMount() { this.setupConnection(); } componentDidUpdate(prevProps, prevState) { if ( this.props.roomId !== prevProps.roomId || this.state.serverUrl !== prevState.serverUrl ) { this.destroyConnection(); this.setupConnection(); } } componentWillUnmount() { this.destroyConnection(); } setupConnection() { this.connection = createConnection( this.state.serverUrl, this.props.roomId ); this.connection.connect(); } destroyConnection() { this.connection.disconnect(); this.connection = null; } render() { return ( <> <label> URL du serveur :{' '} <input value={this.state.serverUrl} onChange={e => { this.setState({ serverUrl: e.target.value }); }} /> </label> <h1>Bienvenue dans le salon {this.props.roomId} !</h1> </> ); } }
Commencez par vérifier que votre componentWillUnmount
fait bien l’inverse de votre componentDidMount
. Dans l’exemple ci-dessus, c’est bien le cas : elle débranche la connexion établie par componentDidMount
. Si cette logique est manquante, commencez par l’ajouter.
Ensuite, vérifiez que votre méthode componentDidUpdate
gère les changements des props et états que vous utilisez dans componentDidMount
. Dans l’exemple ci-dessus, componentDidMount
appelle setupConnection
qui lit this.state.serverUrl
et this.props.roomId
. C’est pourquoi componentDidUpdate
vérifie si this.state.serverUrl
ou this.props.roomId
ont changé, et réinitialise la connexion le cas échéant. Si la logique de votre componentDidUpdate
est manquante ou ne gère pas les changements à toutes les parties pertinentes des props et de l’état, corrigez d’abord ça.
Dans l’exemple qui précède, la logique dans les méthodes de cycle de vie connecte le composant à un système extérieur à React (un serveur de discussion). Pour connecter un composant à un système extérieur, décrivez la logique nécessaire dans un Effet unique :
import { useState, useEffect } from 'react';
function ChatRoom({ roomId }) {
const [serverUrl, setServerUrl] = useState('https://localhost:1234');
useEffect(() => {
const connection = createConnection(serverUrl, roomId);
connection.connect();
return () => {
connection.disconnect();
};
}, [serverUrl, roomId]);
// ...
}
Cet appel à useEffect
est équivalent à la logique des méthodes de cycle de vie ci-avant. Si vos méthodes de cycle de vie s’occupent de plusieurs sujets distincts, découpez-les en Effets indépendants. Voici l’exemple complet que vous pouvez manipuler :
import { useState, useEffect } from 'react'; import { createConnection } from './chat.js'; export default function ChatRoom({ roomId }) { const [serverUrl, setServerUrl] = useState('https://localhost:1234'); useEffect(() => { const connection = createConnection(serverUrl, roomId); connection.connect(); return () => { connection.disconnect(); }; }, [roomId, serverUrl]); return ( <> <label> URL du serveur :{' '} <input value={serverUrl} onChange={e => setServerUrl(e.target.value)} /> </label> <h1>Bienvenue dans le salon {roomId} !</h1> </> ); }
Migrer un composant avec un contexte d’une classe vers une fonction
Dans l’exemple qui suit, les composants à base de classes Panel
et Button
lisent un contexte en utilisant this.context
:
import { createContext, Component } from 'react'; const ThemeContext = createContext(null); class Panel extends Component { static contextType = ThemeContext; render() { const theme = this.context; const className = 'panel-' + theme; return ( <section className={className}> <h1>{this.props.title}</h1> {this.props.children} </section> ); } } class Button extends Component { static contextType = ThemeContext; render() { const theme = this.context; const className = 'button-' + theme; return ( <button className={className}> {this.props.children} </button> ); } } function Form() { return ( <Panel title="Bienvenue"> <Button>Inscription</Button> <Button>Connexion</Button> </Panel> ); } export default function MyApp() { return ( <ThemeContext.Provider value="dark"> <Form /> </ThemeContext.Provider> ) }
Lorsque vous convertissez ça en fonctions composants, remplacez votre utilisation dethis.context
par des appels à useContext
:
import { createContext, useContext } from 'react'; const ThemeContext = createContext(null); function Panel({ title, children }) { const theme = useContext(ThemeContext); const className = 'panel-' + theme; return ( <section className={className}> <h1>{title}</h1> {children} </section> ) } function Button({ children }) { const theme = useContext(ThemeContext); const className = 'button-' + theme; return ( <button className={className}> {children} </button> ); } function Form() { return ( <Panel title="Bienvenue"> <Button>Inscription</Button> <Button>Connexion</Button> </Panel> ); } export default function MyApp() { return ( <ThemeContext.Provider value="dark"> <Form /> </ThemeContext.Provider> ) }