Comment faire pour annuler une opération d'extraction sur componentWillUnmount
Je pense que le titre dit tout. Le jaune d'avertissement est affiché à chaque fois que je démonter un composant qui est toujours en chargement.
Console
Avertissement: ne Peut pas appeler
setState
(ouforceUpdate
) sur une démonté composant. C'est un no-op, mais ... À corriger, annuler tous les abonnements et des tâches asynchrones dans lecomponentWillUnmount
méthode.
constructor(props){
super(props);
this.state = {
isLoading: true,
dataSource: [{
name: 'loading...',
id: 'loading',
}]
}
}
componentDidMount(){
return fetch('LINK HERE')
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
dataSource: responseJson,
}, function(){
});
})
.catch((error) =>{
console.error(error);
});
}
- qu'est-ce que c'avertissement je n'ai pas ce problème
- question mise à jour
- avez-vous une promesse ou asynchrone code pour récupérer
- ajouter vous extraire le code de qustion
- voir isMounted est un Antipattern et avorter un fetch.
Vous devez vous connecter pour publier un commentaire.
Quand vous tirez une Promesse, il pourrait prendre quelques secondes avant qu'il ne décide de l'utilisateur pourrait avoir navigué vers un autre endroit dans votre application. Ainsi, lorsque la Promesse résout
setState
est exécuté sur démonté composant et vous obtenez une erreur, tout comme dans votre cas. Cela peut également provoquer des fuites de mémoire.C'est pourquoi il est préférable de déplacer une partie de votre logique asynchrone à partir de composants.
Sinon, vous aurez besoin de quelque sorte annuler votre Promesse. Alternativement comme un dernier recours technique (c'est un antipattern) - vous pouvez garder une variable afin de vérifier si le composant est toujours monté:
Je vais souligner qu'encore une fois - ce est un antipattern mais peut être suffisant dans ton cas (comme ils l'ont fait avec
Formik
mise en œuvre).Une discussion similaire sur GitHub
EDIT:
C'est probablement comment pourrais-je résoudre le même problème (qui n'ont rien mais Réagir) avec Crochets:
OPTION A:
OPTION B: Alternativement avec
useRef
qui se comporte comme une propriété statique d'une classe, ce qui signifie qu'il ne fait pas de composant rerender quand c'est les changements de la valeur:Exemple: https://codesandbox.io/s/86n1wq2z8
setting getter-only property
De la gentillesse des gens à Réagir recommander d'emballage de votre extraction des appels/des promesses dans un annulable promesse. Alors qu'il n'y a pas de recommandation à ce que la documentation pour avoir un code distinct de la classe ou d'une fonction avec le chercher, ce qui semble souhaitable parce que les autres classes et les fonctions sont susceptibles d'avoir besoin de cette fonctionnalité, la duplication de code est un anti-modèle, et quelle que soit la lenteur de code doivent être éliminés ou annulée dans
componentWillUnmount()
. Comme par Réagir, vous pouvez appelercancel()
sur le enveloppés promesse danscomponentWillUnmount
afin d'éviter la création de l'état sur une démonté composant.Le code fourni ressemblerait à quelque chose comme ces extraits de code si nous utilisons Réagir comme un guide:
---- EDIT ----
J'ai trouvé la réponse donnée ne peut pas être tout à fait exact par la suite de la question sur GitHub. Voici une version que j'utilise, qui travaille pour mes fins:
L'idée était d'aider le garbage collector de libérer de la mémoire en faisant de la fonction ou ce que vous utilisez la valeur null.
Vous pouvez utiliser AbortController pour annuler une demande de récupération.
JS:
HTML:
Depuis le poste a été ouvert, un "abortable-fetch" a été ajouté.
https://developers.google.com/web/updates/2017/09/abortable-fetch
(à partir de la doc:)
Le contrôleur + signal de manœuvre
Répondre à la AbortController et AbortSignal:
Le contrôleur dispose d'une seule méthode:
contrôleur.abort();
Lorsque vous faites cela, il en informe le signal:
Cette API est fournie par le DOM standard, et c'est l'ensemble de l'API. C'est délibérément générique de sorte qu'il peut être utilisé par d'autres standards du web et les bibliothèques JavaScript.
par exemple, voici comment vous pouvez faire une extraction expire au bout de 5 secondes:
Quand j'en ai besoin "annuler tous les abonnements et asynchrone" j'ai l'habitude d'expédition quelque chose de redux en componentWillUnmount d'informer tous les autres abonnés et de l'envoyer encore une demande d'annulation de serveur si nécessaire
L'essentiel de cet avertissement, c'est que votre composant a une référence à ce qui est tenu par une partie de rappel/promesse.
Pour éviter la antipattern de garder votre isMounted état (ce qui maintient votre composant vivant) comme cela a été fait dans le deuxième modèle, la réagir site suggère en utilisant une option de la promesse; cependant, ce code apparaît également à garder votre objet vivant.
Au lieu de cela, je l'ai fait par à l'aide d'une fermeture avec un imbriquée lié fonction de setState.
Voici mon constructeur(tapuscrit)...
this
Je pense que j'ai pensé à un moyen de contourner cela. Le problème n'est pas tant l'extraction elle-même, mais le setState une fois que le composant est rejeté. Donc la solution était de mettre en
this.state.isMounted
commefalse
puis surcomponentWillMount
changer pour vrai, et danscomponentWillUnmount
la valeur false à nouveau. Puis justeif(this.state.isMounted)
la setState à l'intérieur de l'extraction. Comme: