Dans React, lorsqu'un composatn parent est mis à jour, ses enfants peuvent subir des re-rendus même si leurs props restent iedntiques, ce qui affecte les performances. Voici trois approches pour résoudre ce problème : shouldComponentUpdate, PureComponent et React.memo.
Utilisation de shouldComponentUpdate
Cette méthode de cycle de vie permet de définir manuellement les conditions de re-rendu en comparant les nouvelles props avec les actuelles.
class ComposantEnfant extends Component {
shouldComponentUpdate(nextProps) {
if (nextProps.valeur === this.props.valeur) {
return false;
}
return true;
}
render() {
console.log("Rendu de l'enfant");
return null;
}
}
class ComposantParent extends Component {
state = {
compteur: 0,
autre: 0
}
render() {
return (
<div>
<ComposantEnfant valeur={this.state.compteur} />
<button onClick={() => this.setState(prev => ({ compteur: prev.compteur + 1 }))}>Inc compteur</button>
<button onClick={() => this.setState(prev => ({ autre: prev.autre + 1 }))}>Inc autre</button>
</div>
);
}
}
Utilisation de PureComponent
PureComponent effectue une comparaison superficielle des props et du state pour déclencher un re-rendu uniqueemnt en cas de changement détecté.
import React, { PureComponent } from 'react';
class EnfantPur extends PureComponent {
render() {
console.log("Rendu de l'enfant pur");
return null;
}
}
class ParentOptimise extends Component {
state = {
compteur: 0,
autre: 0
}
render() {
return (
<div>
<EnfantPur compteur={this.state.compteur} />
<button onClick={() => this.setState(prev => ({ compteur: prev.compteur + 1 }))}>Inc compteur</button>
<button onClick={() => this.setState(prev => ({ autre: prev.autre + 1 }))}>Inc autre</button>
</div>
);
}
}
Utilisation de React.memo pour les composants fonctionnels
React.memo enveloppe un composant fonctionnel pour éviter les re-rendus lorsque les props n'ont pas changé.
import React, { Component, memo } from 'react';
const EnfantMemo = memo(function EnfantMemo(props) {
console.log("Rendu de l'enfant memo");
return <div>Valeur : {props.valeur}</div>;
});
class ParentAvecMemo extends Component {
state = {
compteur: 0,
autre: 0
}
render() {
return (
<div>
<EnfantMemo valeur={this.state.compteur} />
<button onClick={() => this.setState(prev => ({ compteur: prev.compteur + 1 }))}>Inc compteur</button>
<button onClick={() => this.setState(prev => ({ autre: prev.autre + 1 }))}>Inc autre</button>
</div>
);
}
}