Ich hole Daten in ComponentDidMount ab und aktualisiere den Status. Die berühmte Warnung wird angezeigt:
Warnung: setState (oder forceUpdate) kann für eine nicht bereitgestellte Komponente nicht aufgerufen werden. Dies ist ein No-Op, weist jedoch auf einen Speicherverlust in Ihrer Anwendung hin. Brechen Sie zum Beheben alle Subskriptionen und asynchronen Tasks in der Methode componentWillUnmount ab.
Mein Code lautet wie folgt:
componentDidMount() {
let self = this;
let apiBaseUrl = Config.serverUrl;
axios.get( apiBaseUrl + '/dataToBeFetched/' )
.then( function(response) {
self.setState( { data: response.data } );;
} );
}
Was verursacht diese Warnung und wie kann man die Daten am besten abrufen und den Status aktualisieren?
Basierend auf einer vorherigen Antwort habe ich Folgendes getan, was gut funktioniert hat:
constructor(props) {
this.state = {isMounted: false}
}
componentDidMount() {
let apiBaseUrl = Config.serverUrl;
this.setState( { isMounted: true }, () => {
axios.get( apiBaseUrl + '/dataToBeFetched/' )
.then( (response) => { // using arrow function ES6
if( this.state.isMounted ) {
this.setState( { pets: response.data } );
}
} ).catch( error => {
// handle error
} )
} );
}
componentWillUnmount() {
this.setState( { isMounted: false } )
}
Eine andere bessere Lösung ist, die Anforderung im Unmount wie folgt abzubrechen:
constructor(props) {
this._source = axios.CancelToken.source();
}
componentDidMount() {
let apiBaseUrl = Config.serverUrl;
axios.get( apiBaseUrl + '/dataToBeFetched/', { cancelToken: this._source.token } )
.then( (response) => { // using arrow function ES6
if( this.state.isMounted ) {
this.setState( { pets: response.data } );
}
} ).catch( error => {
// handle error
} );
}
componentWillUnmount() {
this._source.cancel( 'Operation canceled due component being unmounted.' )
}
Sie können dies versuchen:
constructor() {
super();
this._isMounted = false;
}
componentDidMount() {
this._isMounted = true;
let apiBaseUrl = Config.serverUrl;
this.setState( { isMounted: true }, () => {
axios.get( apiBaseUrl + '/dataToBeFetched/' )
.then( (response) => { // using arrow function ES6
if( this._isMounted ) {
this.setState( { pets: response.data } );
}
} ).catch( error => {
// handle error
} )
} );
}
componentWillUnmount() {
this._isMounted = false; // equals, not :
}
Dies ist höchstwahrscheinlich der Fall, weil die Komponente bereits vor dem Ende des asynchronen Aufrufs abgemeldet wurde. Das heißt, Ihr Aufruf an setState
im Axios-Versprechen wird aufgerufen, nachdem die Komponente bereits ausgehängt wurde, möglicherweise aufgrund einer react-router
-Umleitung oder einer Statusänderung.
Der Aufruf von setState
auf componentWillUnmount
ist die schlechteste Vorgehensweise
componentWillUnmount() {
this.setState( { isMounted: false } ) // don't do this
}