2017-12-21 3 views
1

Ich bin neu in React, also ist das wahrscheinlich nur ein Anfängerfehler.Fehler bei ComponentDidMount reagieren -> Kann nur eine gemounted oder mounting Komponente aktualisieren?

Zusammenfassend wird der Fehler/Warnung erwähnt und es wird zweimal ausgeführt. Es endet jedoch mit dem korrekten Endergebnis.

Die Einrichtung ist eine Seite zum Anzeigen grundlegender Benutzerprofilinformationen mit Funktionen zum Ändern des Profils, die später hinzugefügt werden.

Details:

  • componentDidMount scheint einmal aufgerufen werden, gemäß der console.log Ausgabe unter

  • Abruf wird aus irgendeinem Grunde zweimal genannt. Beide Male erhält es die richtigen Informationen von Remote

  • this.setState ({account.data.data [0]}) schlägt das erste Mal um und wirft den Fehler. Dies ist besonders seltsam, da schlägt vor, dass die Komponente nicht montiert ist, während es in ComponentDidMount aufgerufen wird. Das zweite Mal, wenn fetch und setState ausgeführt werden, wird der Status korrekt aktualisiert.

Die genaue Fehlermeldung:

Warnung: Kann nur ein bereitgestelltes oder Montagekomponente aktualisieren. Dies bedeutet normalerweise, dass Sie setState, replaceState oder forceUpdate für eine nicht bereitgestellte Komponente aufgerufen haben. Dies ist ein No-Op.

Dies ist die wichtigste Komponente:

class AccountTable extends React.Component{ 

constructor(props){ 
    super(props) 
    this.state={ 
     account:{}, 
    } 
} 

componentDidMount(){ 
    console.log('componentDidMount');//outputs once 
    fetch('/mon-compte-api', { 
     method: 'get', 
     credentials: 'same-origin' 
    }) 
    .then((response) => { 
     console.log('fetch'); // outputs twice 
     response.json().then((data) => { 
      console.log('data', data);// correct output both times 
      this.setState({account: data.data[0]}) // this throws the error 
      console.log('state_account', this.state.account); 
// no output for this.state.account first time around. Correct output 2nd time 
     })  
    }) 
    .catch((err) => { 
     console.log(err) 
    });  
} 

render(){ 
    return (
     <table> 
       <TableRow 
        account={this.state.account} /> 
     </table> 
    );  
} 
} 

ReactDOM.render(<AccountTable />,document.querySelector("#react_account")); 

Dies ist die untergeordnete Komponente:

const TableRow = (props) => { 
if(Object.keys(props.account).length === 0){ //show something while awaiting fetch 
    return (
     <tbody> 
      <tr><td>Loading.....</td></tr> // shows momentarily 
     </tbody> 
     ); 
}else{ 
     return (// outputs correct info eventually 
      <tbody> 
       <tr><th>Name</th><td>{props.account.name}</td></tr> 
       <tr><th>Email</th><td>{props.account.email}</td></tr> 
      </tbody> 
     ); 
} 
} 

Antwort Informationen angefordert:

Status code: 200 OK 
Date: Thu, 21 Dec 2017 11:53:50 GMT 
Server: Apache/2.2.32 (Unix) mod_wsgi/3.5 Python/2.7.13 PHP/7.1.8  mod_ssl/2.2.32 OpenSSL/1.0.2j DAV/2 mod_fastcgi/2.4.6 mod_perl/2.0.9 Perl/v5.24.0 
X-Powered-By: PHP/7.1.8 
Cache-Control: no-cache, private 
Content-Length: 600 
Keep-Alive: timeout=5, max=99 
Connection: Keep-Alive 
Content-Type: application/json 
+0

ich glaube, das Problem innerhalb der Eltern von AccountTable liegt, können Sie den Code hier posten? –

+0

Log voll 'Antwort' Status-Code und Header, kann es etwas mit der Art zu tun haben, die Sie authentifizieren. Vielleicht erhalten Sie beim ersten Anruf eine 401, in der Sie um die Authentifizierung gebeten werden, und dann ruft fetch mit Ihren Zugangsdaten einen zweiten Anruf auf. Die Dokumentation zum Abrufen konnte nicht gefunden werden, ist aber im Anforderungsmodul ausführlich beschrieben: https://github.com/request/request#http-authentication –

+0

@GabrielBleu, danke. Ich habe die Antwort oben hinzugefügt. Es ist 200 OK. – BernardA

Antwort

0

Versuchen isMounted in Komponente Zustand. Sie müssen überprüfen, ob die Komponente montiert oder montiert ist, und dann setState() ausführen.

Wegen asynchroner Operationen Existenz in Ihrer Komponente Lebenszyklus macht, wird es besser sein zu verwenden funktionellesetState().

Set isMounted Zustand in der Initialisierung als true.

constructor(props){ 
    super(props) 
    this.state={ 
     isMounted: true 
     account:{}, 
    } 
} 

dann ändern this.state.isMounted-false wenn componentWillUnmount() läuft.

componentWillUnmount(){ 
    this.setState({ 
    isMounted: false 
    }) 
} 

und dann schauen Sie in this.state.isMounted mit funktionellen setState() vor this.setState({account: data.data[0]}) tun:

.then((response) => { 
     console.log('fetch'); // outputs twice 
     response.json().then((data) => { 
      console.log('data', data);// correct output both times 
      this.setState(function (state, props) { // Functional setState 
       if(state.isMounted){ 
         return { 
          account: data.data[0] 
         } 
       } 
      }); 
      console.log('state_account', this.state.account); 
      // no output for this.state.account first time around. Correct output 2nd time 
     })  
}) 
+0

danke, aber das schien es nicht zu lösen. Es würde Sinn machen, da isMounted nicht wirklich die initiale Einrichtung beeinflusst. Auch hier läuft der Code innerhalb von componentDidMount. Die Komponente sollte per Definition angehängt werden. – BernardA

+0

Die Komponente muss nicht montiert werden. weil Sie eine asynchrone Funktion 'fetch() aufrufen, dann (...)' und sie kann abgehängt werden, wenn 'then()' Methode aufruft. Wenn Sie mir erlauben, werde ich meine Antwort nicht entfernen. Vielleicht hilft diese Antwort jemand anderem. –

Verwandte Themen