Le crochet seEffect React exécutera la fonction transmise à chaque modification. Ceci peut être optimisé pour ne le laisser appeler que lorsque les propriétés souhaitées changent.
Que faire si je souhaite appeler une fonction d'initialisation à partir de componentDidMount
et ne pas l'appeler à nouveau lors d'une modification? Supposons que je veuille charger une entité, mais que la fonction de chargement ne nécessite aucune donnée du composant. Comment pouvons-nous faire cela en utilisant le hook useEffect
?
class MyComponent extends React.PureComponent {
componentDidMount() {
loadDataOnlyOnce();
}
render() { ... }
}
Avec les crochets, cela pourrait ressembler à ceci:
function MyComponent() {
useEffect(() => {
loadDataOnlyOnce(); // this will fire on every change :(
}, [...???]);
return (...);
}
Si vous voulez seulement exécuter la fonction donnée à useEffect
après le rendu initial, vous pouvez lui donner un tableau vide comme second argument.
function MyComponent() {
useEffect(() => {
loadDataOnlyOnce();
}, []);
return <div> {/* ... */} </div>;
}
TL; DR
useEffect(yourCallback, [])
- ne déclenchera le rappel qu'après le premier rendu.
Explication détaillée
useEffect
s'exécute par défaut après le rendu de tous les du composant (ce qui provoque un effet).
Lorsque vous insérez useEffect
dans votre composant, vous indiquez React que vous souhaitez exécuter le rappel en tant qu'effet. React exécutera l'effet après le rendu et les mises à jour DOM.
Si vous ne passez qu'un rappel - le rappel s'exécutera après chaque rendu.
Si vous passez un deuxième argument (array), React exécutera le rappel après le premier rendu et à chaque fois que l'un des éléments du tableau est modifié. par exemple, lorsque vous placez useEffect(() => console.log('hello'), [someVar, someOtherVar])
- le rappel s'exécutera après le premier rendu et après tout rendu, l'un des someVar
ou someOtherVar
sera modifié.
En transmettant au second argument un tableau vide, React comparera après chaque rendu du tableau et ne verra rien changé, appelant ainsi le rappel uniquement après le premier rendu.
Passez un tableau vide comme second argument à useEffect
. Ceci indique effectivement à React, citant le docs :
Ceci indique à React que votre effet ne dépend d'aucune valeur provenant de props ou state, il n'a donc jamais besoin d'être réexécuté.
Voici un extrait que vous pouvez exécuter pour montrer que cela fonctionne:
function App() {
const [user, setUser] = React.useState(null);
React.useEffect(() => {
fetch('https://randomuser.me/api/')
.then(results => results.json())
.then(data => {
setUser(data.results[0]);
});
}, []); // Pass empty array to only run once on mount.
return <div>
{user ? user.name.first : 'Loading...'}
</div>;
}
ReactDOM.render(<App/>, document.getElementById('app'));
<script src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>
<div id="app"></div>
L'exécution d'une fonction une seule fois après le montage des composants est un modèle si courant qu'il justifie son propre crochet masquant les détails de la mise en œuvre.
const useMountEffect = (fun) => useEffect(fun, [])
Utilisez-le dans n'importe quel composant fonctionnel.
function MyComponent() {
useMountEffect(function) // function will run only once after it has mounted.
return <div>...</div>;
}
À propos du hook useMountEffect
Lorsque vous utilisez useEffect
avec un deuxième argument de tableau, React exécute le rappel après le montage (rendu initial) et après que les valeurs du tableau ont changé. Comme nous passons un tableau vide, il ne fonctionnera qu’après le montage.