Permettez-moi d'expliquer le résultat de ce code pour poser mon problème facilement.
const ForExample = () => {
const [name, setName] = useState('');
const [username, setUsername] = useState('');
useEffect(() => {
console.log('effect');
console.log({
name,
username
});
return () => {
console.log('cleaned up');
console.log({
name,
username
});
};
}, [username]);
const handleName = e => {
const { value } = e.target;
setName(value);
};
const handleUsername = e => {
const { value } = e.target;
setUsername(value);
};
return (
<div>
<div>
<input value={name} onChange={handleName} />
<input value={username} onChange={handleUsername} />
</div>
<div>
<div>
<span>{name}</span>
</div>
<div>
<span>{username}</span>
</div>
</div>
</div>
);
};
Lorsque ForExample component
Monte, "effet" sera enregistré. Ceci est lié à la componentDidMount()
.
Et chaque fois que je modifie la saisie du nom, "effet" et "nettoyé" seront enregistrés. Inversement, aucun message ne sera enregistré chaque fois que je changerai le nom d'utilisateur car j'ai ajouté [username]
Au deuxième paramètre de useEffect()
. Ceci est lié à la componentDidUpdate()
Enfin, lorsque ForExample component
Sera démonté, "nettoyé" sera enregistré. Ceci est lié à la componentWillUnmount()
.
Nous savons tous que.
Pour résumer, "nettoyé" est invoqué chaque fois que le composant est restitué (inclut le démontage)
Si je veux que ce composant se connecte "nettoyé" uniquement pour le moment où il est démonté, je dois simplement changer le deuxième paramètre de useEffect()
en []
.
Mais si je change [username]
En []
, ForExample component
N'implémente plus la componentDidUpdate()
pour la saisie du nom.
Ce que je veux faire, c'est que, pour que le composant prenne en charge à la fois componentDidUpdate()
uniquement pour la saisie de nom et componentWillUnmount()
. (enregistrement "nettoyé" uniquement pour le moment où le composant est démonté)
Étant donné que le nettoyage ne dépend pas du username
, vous pouvez placer le nettoyage dans un useEffect
distinct auquel est attribué un tableau vide comme deuxième argument.
Exemple
const { useState, useEffect } = React;
const ForExample = () => {
const [name, setName] = useState("");
const [username, setUsername] = useState("");
useEffect(
() => {
console.log("effect");
},
[username]
);
useEffect(() => {
return () => {
console.log("cleaned up");
};
}, []);
const handleName = e => {
const { value } = e.target;
setName(value);
};
const handleUsername = e => {
const { value } = e.target;
setUsername(value);
};
return (
<div>
<div>
<input value={name} onChange={handleName} />
<input value={username} onChange={handleUsername} />
</div>
<div>
<div>
<span>{name}</span>
</div>
<div>
<span>{username}</span>
</div>
</div>
</div>
);
};
function App() {
const [shouldRender, setShouldRender] = useState(true);
useEffect(() => {
setTimeout(() => {
setShouldRender(false);
}, 5000);
}, []);
return shouldRender ? <ForExample /> : null;
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>
vous pouvez utiliser plus d'une utilisation
par exemple, si ma variable est data1, je peux utiliser tout cela dans mon composant
useEffect( () => console.log("mount"), [] );
useEffect( () => console.log("will update data1"), [ data1 ] );
useEffect( () => console.log("will update any") );
useEffect( () => () => console.log("will update data1 or unmount"), [ data1 ] );
useEffect( () => () => console.log("unmount"), [] );
function LegoComponent() {
const [lego, setLegos] = React.useState([])
React.useEffect(() => {
let isSubscribed = true
fetchLegos().then( legos=> {
if (isSubscribed) {
setLegos(legos)
}
})
return () => isSubscribed = false
}, []);
return (
<ul>
{legos.map(lego=> <li>{lego}</li>)}
</ul>
)
}
Dans le code ci-dessus, la fonction fetchLegos renvoie une promesse. Nous pouvons "annuler" la promesse en ayant un conditionnel dans la portée de useEffect, empêchant l'application de définir l'état après le démontage du composant.
Avertissement: impossible d'effectuer une mise à jour d'état React sur un composant non monté. Il s'agit d'un no-op, mais il indique une fuite de mémoire dans votre application. Pour corriger, annulez tous les abonnements et tâches asynchrones dans une fonction de nettoyage useEffect.