Dans mon composant de réaction, j'essaie d'implémenter un simple spinner pendant qu'une requête ajax est en cours - j'utilise l'état pour stocker l'état de chargement.
Pour une raison quelconque, ce morceau de code ci-dessous dans mon composant React lève cette erreur
Peut uniquement mettre à jour un composant monté ou de montage. Cela signifie généralement que vous avez appelé setState () sur un composant non monté. C'est un no-op. Veuillez vérifier le code du composant non défini.
Si je me débarrasse du premier appel setState, l'erreur disparaît.
constructor(props) {
super(props);
this.loadSearches = this.loadSearches.bind(this);
this.state = {
loading: false
}
}
loadSearches() {
this.setState({
loading: true,
searches: []
});
console.log('Loading Searches..');
$.ajax({
url: this.props.source + '?projectId=' + this.props.projectId,
dataType: 'json',
crossDomain: true,
success: function(data) {
this.setState({
loading: false
});
}.bind(this),
error: function(xhr, status, err) {
console.error(this.props.url, status, err.toString());
this.setState({
loading: false
});
}.bind(this)
});
}
componentDidMount() {
setInterval(this.loadSearches, this.props.pollInterval);
}
render() {
let searches = this.state.searches || [];
return (<div>
<Table striped bordered condensed hover>
<thead>
<tr>
<th>Name</th>
<th>Submit Date</th>
<th>Dataset & Datatype</th>
<th>Results</th>
<th>Last Downloaded</th>
</tr>
</thead>
{
searches.map(function(search) {
let createdDate = moment(search.createdDate, 'X').format("YYYY-MM-DD");
let downloadedDate = moment(search.downloadedDate, 'X').format("YYYY-MM-DD");
let records = 0;
let status = search.status ? search.status.toLowerCase() : ''
return (
<tbody key={search.id}>
<tr>
<td>{search.name}</td>
<td>{createdDate}</td>
<td>{search.dataset}</td>
<td>{records}</td>
<td>{downloadedDate}</td>
</tr>
</tbody>
);
}
</Table >
</div>
);
}
La question est pourquoi j'obtiens cette erreur alors que le composant devrait déjà être monté (comme il est appelé à partir de componentDidMount) J'ai pensé qu'il était sûr de définir l'état une fois que le composant est monté?
la source
this.state = { loading : null };
Réponses:
Sans voir la fonction de rendu, c'est un peu dur. Bien que vous puissiez déjà repérer quelque chose que vous devriez faire, chaque fois que vous utilisez un intervalle, vous devez l'effacer au démontage. Alors:
Étant donné que ces rappels de succès et d'erreur peuvent toujours être appelés après le démontage, vous pouvez utiliser la variable d'intervalle pour vérifier si elle est montée.
J'espère que cela aide, fournissez la fonction de rendu si cela ne fait pas le travail.
À votre santé
la source
componentWillUnmount() { clearInterval(this.loadInterval); }
Il n'est pas appelé depuis
componentDidMount
. VotrecomponentDidMount
génère une fonction de rappel qui sera exécutée dans la pile du gestionnaire de minuterie, et non dans la pile decomponentDidMount
. Apparemment, au moment où votre callback (this.loadSearches
) est exécuté, le composant s'est démonté.Ainsi, la réponse acceptée vous protégera. Si vous utilisez une autre API asynchrone qui ne vous permet pas d'annuler les fonctions asynchrones (déjà soumises à un gestionnaire), vous pouvez effectuer les opérations suivantes:
Cela éliminera le message d'erreur que vous signalez dans tous les cas, même si cela donne l'impression de balayer des choses sous le tapis, en particulier si votre API fournit une capacité d'annulation (comme le
setInterval
faitclearInterval
).la source
isMounted
est un anti-modèle que facebook conseille de ne pas utiliser: facebook.github.io/react/blog/2015/12/16/…Pour qui a besoin d'une autre option, la méthode de rappel de l'attribut ref peut être une solution de contournement. Le paramètre de handleRef est la référence à l'élément DOM div.
Pour des informations détaillées sur les refs et DOM: https://facebook.github.io/react/docs/refs-and-the-dom.html
la source
la source
Pour la postérité,
Cette erreur, dans notre cas, était liée à Reflux, aux rappels, aux redirections et à setState. Nous avons envoyé un setState à un rappel onDone, mais nous avons également envoyé une redirection vers le rappel onSuccess. En cas de succès, notre rappel onSuccess s'exécute avant le onDone . Cela provoque une redirection avant la tentative setState . Ainsi l'erreur, setState sur un composant non monté.
Action du magasin de reflux:
Appelez avant la correction:
Appel après correction:
Plus
Dans certains cas, puisque isMounted de React est "obsolète / anti-pattern", nous avons adopté l'utilisation d'une variable _mounted et la surveillons nous-mêmes.
la source
Partagez une solution activée par les hooks de réaction .
la même solution peut être étendue à chaque fois que vous souhaitez annuler les demandes précédentes sur les changements d'id de récupération, sinon il y aurait des conditions de concurrence entre plusieurs demandes en cours (
this.setState
appelées dans le désordre).cela fonctionne grâce aux fermetures en javascript.
En général, l'idée ci-dessus était proche de l' approche makeCancelable recommandée par le react doc, qui énonce clairement
Crédit
https://juliangaramendy.dev/use-promise-subscription/
la source