2017-05-11 4 views
0

Ich bin neu zu reagieren. Ich versuche, Daten von Remote-Server mit _fetchUsers() dynamisch abzurufen. Der Status apiUrl sollte geändert werden, wenn Sie auf verschiedene nav tabs klicken, obwohl sie hier nicht angezeigt werden. Die Probleme, ich finde, dass das Protokoll vor $.ajax Funktion zeigt leere Zeichenfolge von this.state.apiurl. Wenn ich die URL auf der URL-Eigenschaft von ajax fest codiere, kann der Ajax die richtige Antwort zurückgeben. Kann jemand erklären, warum ich für die apiurl SetState scheitern, ist die zu componentWillMount() Zusammenhang GrundReact konnte den Status in der Funktion, die in componentWillMount() aufgerufen wurde, nicht setzen

export default class RegiteredUserTable extends Component { 
 
    constructor() { 
 
     super(); 
 
     this.state = { 
 
      registeredUsers:[], 
 
      tableProperties:[], 
 
      apiUrl:'' 
 
     } 
 
    } 
 
    _fetchUsers() { 
 
     console.log("this.props", this.props); 
 
     if(this.props.match.params.tableId === "buyer-table"){ 
 
      this.setState({apiUrl:'/buyers/list-buyers'}); 
 
     } else if (this.props.match.params.tableId === "seller-table") { 
 
      this.setState({apiUrl:'/sellers/list-sellers/'}); 
 
     } 
 
     console.log('this.state.apiUrl',this.state.apiUrl);  
 
     $.ajax({ 
 
      method: 'GET', 
 
      url: `${this.state.apiUrl}`, 
 
      success: (res) => { 
 
       console.log('res',res); 
 
       let registeredUsers = res.data; 
 
       this.setState({registeredUsers}); 
 
      } 
 
     }); 
 
    } 
 

 
    _getTableProperty() { 
 
     //property array 
 
     console.log('this.state.registeredUsers',this.state.registeredUsers); 
 
     const tableProperties = this.state.registeredUsers[0].keys; 
 
     this.setState({tableProperties}); 
 
     return tableProperties.map(tableProperty => { 
 
      return (
 
         <th>{tableProperty}</th> 
 
        ) 
 
     }) 
 
    } 
 

 
    _getUsers() { 
 
     return this.state.registeredUsers.map(registeredUser => { 
 
       return (
 
        <tr> 
 
         <td>{registeredUser.id}</td> 
 
         <td>{registeredUser.first_name}</td> 
 
         <td>{registeredUser.last_name}</td> 
 
        </tr> 
 
       ); 
 
      } 
 
     ) 
 
    } 
 
    componentWillMount() { 
 
     this._fetchUsers(); 
 
    } 
 
    render() { 
 
     return(
 
      <div className="container"> 
 
       <div className="row"> 
 
        <div className="col-xs-12"> 
 
        <div className="table-responsive"> 
 
         <table className="table table-bordered table-hover"> 
 
         <caption className="text-center">Agents' data</caption> 
 
         <thead> 
 
          <tr> 
 
           {this._getTableProperty()} 
 
          </tr> 
 
         </thead> 
 
         <tbody> 
 
          {this._getUsers()} 
 
         </tbody> 
 
         <tfoot> 
 
          <tr> 
 
          <td colSpan="5" className="text-center">Data retrieved from <a href="http://www.infoplease.com/ipa/A0855611.html" target="_blank">infoplease</a> and <a href="http://www.worldometers.info/world-population/population-by-country/" target="_blank">worldometers</a>.</td> 
 
          </tr> 
 
         </tfoot> 
 
         </table> 
 
        </div> 
 
        </div> 
 
       </div> 
 
      </div> 
 

 
     ); 
 
    } 
 
}

+0

Überprüfung der Grund, hier setState ist async: http://stackoverflow.com/questions/42593202/why-calling-setstate-method-doesnt-mutate-the-state-immediately –

Antwort

0

SetState ist async, so der API-Aufruf tun, wenn setState stellen Sie die apiUrl in state Variable , verwenden Sie eine Callback-Methode und führen Sie den API-Aufruf darin aus.

Schreiben Sie die _fetchUsers wie folgt aus:

_fetchUsers() { 
    let tableId = this.props.match.params.tableId; 

    this.setState({ 
     apiUrl: tableId === "buyer-table" ? '/buyers/list-buyers' : '/sellers/list-sellers/' 
    },() => { 
     $.ajax({ 
      method: 'GET', 
      url: `${this.state.apiUrl}`, 
      success: (res) => { 
       console.log('res',res); 
       let registeredUsers = res.data; 
       this.setState({registeredUsers}); 
      } 
     }); 
    });  
} 

Oder besser Weise speichert sein nur die apiUrl in einer Variablen und tun setState, wenn Sie die Antwort erhalten, durch diese Weise brauchen Sie nicht setState zweimal zu tun und müssen nicht zuerst von setState abhängen.

So:

_fetchUsers() { 
    let tableId = this.props.match.params.tableId; 
    let url = tableId === "buyer-table" ? '/buyers/list-buyers' : '/sellers/list-sellers/'; 
    $.ajax({ 
     method: 'GET', 
     url: url, 
     success: (res) => { 
      console.log('res',res); 
      let registeredUsers = res.data; 
      this.setState({registeredUsers, apiUrl: url}); 
     } 
    });  
} 
+0

Sie sollten 'const', nicht' let' verwenden, wenn sich der Wert nicht ändert. – Sulthan

+0

@Sultan dankt, werde die Änderungen vornehmen :) –

+0

Hallo, Ich habe Ihre Methode verwendet und habe die richtigen Daten für den Zustand der apiUrl in meinem Protokoll angezeigt. Ich habe jedoch ein anderes Problem gefunden. Das Protokoll für den Status von registredUsers innerhalb der Funktion _getTableProperty() ist noch leer. Ich dachte, ich habe _fetchUsers() aufgerufen, um den Status registredUsers in der Funktion componentWillMount() zu setzen, um ihn vor dem Rendern bereit zu machen, aber tatsächlich verhält er sich gemäß meinen Log-Informationen nicht wie ich denke. Warum das? –

Verwandte Themen