2017-01-09 5 views
0

Ich lerne reactjs und habe Probleme beim Aktualisieren einer Komponente, wenn sie eine Nachricht über socket.io empfängt. Es funktioniert, wenn die Komponente anfänglich erstellt wird, aber jedes Mal danach muss sie zweimal aufgerufen werden, bevor die korrekten Daten angezeigt werden.Verwendung von socket.io in reactjs lifecycle Methoden

  1. Zum Beispiel klicke ich auf eine Menüschaltfläche und die Komponente fordert die Daten vom Server an. Der Server sendet das Ergebnis zurück und die Komponente wird korrekt angezeigt. Da die Komponente von Grund auf neu erstellt wird, funktioniert sie perfekt.

  2. Ich klicke auf eine andere Menüschaltfläche, aber die Komponente wurde bereits wie oben erstellt. Die Menüschaltfläche fordert Daten vom Server an und der Server gibt das Ergebnis zurück, aber die Komponente aktualisiert und zeigt sie nicht an. Wenn Sie jedoch auf eine andere Menüschaltfläche klicken, zeigt die Komponente das vorherige vom Server gesendete Ergebnis an (die Komponente ist also immer nur ein Klick dahinter).

Ich verstehe, warum ist nicht Arbeits ist (wegen der Asynchron-Natur von Web-dev), aber ich habe keine Ahnung, wie die Komponente erhalten reagieren zu tun, was ich beabsichtige. Ich habe die verschiedenen Lebenszyklus-Methoden ermüdet. Allgemeine Verbesserungen an meinem Reaktionscode sind willkommen.

import React, { Component } from 'react'; 
    import io from 'socket.io-client'; 
    const socket = io('http://localhost:8080/'); 

    import DataTable from './DataTable' 


    const headers = []; 
    const rows = []; 

    export default class Form extends Component { 
     constructor(props) { 
      super(props); 

     this.state = { 
      headers, 
      rows 
     }; 

     this.sortData = this.sortData.bind(this); 

    } 

    sortData(column) { 
     var data = this.state.rows.slice(); //copy data 
     data.sort((a, b) => { 
      return a[column] > b[column]? 1: -1; 

     }); 
     this.setState({rows: data}); 

    } 

    _getData(){ 
     //Request the data from the server 
     socket.emit('get_data', this.props.location.query.option); 
    } 

    _receiveData(){ 
    socket.on(`data_result`, data => { 
     this.setState({rows: data, 
     headers: Object.keys(data[0])}); 
    }); 
    } 

    componentDidMount() { 
     //Request the result from the server and then use the result to render to component. 
     this._getData(); 
     this._receiveData(); 
    } 

    componentWillReceiveProps(nextProps){ 
    //Needed so the component reacts to new input after component creation (component receives a new this.props.location.query.option to send to the server). Doesn't work as needed as it doesn't re-render when it gets a response from the server. 

     this._getData(); 
     this._receiveData(); 
    } 

    render() { 
     return (
      <div> 
       <DataTable form={this.props.location.query.option} 
          headers={this.state.headers} rows={this.state.rows} 
          sortData={this.sortData}/> 
      </div> 
     ); 

    } 

} 
+0

Sie rufen _receiveData im Konstruktor, componentDidMount und componentWillRecieveProps auf. Ich würde vorschlagen, den Aufruf in componentDidMount einmal zu machen. Sie können auch die zwei setState-Befehle, die Sie haben, in einen zusammenfassen. Fixieren Sie diese und sehen Sie, ob das Ihrer Situation hilft –

+0

Danke. Ich habe den Code so bearbeitet, dass er Ihre Vorschläge enthält. Die Verwendung von componentWillRecieveProps verhindert jedoch, dass die Komponente nach der Ersteinrichtung aktualisiert wird. Daher habe ich versucht, mit componentWillRecieveProps auf einen neuen Buttonklick zu reagieren. – Codematcha

Antwort

0

Ich endlich herausgefunden. Während 'componentWillReceiveProps (nextProps)' habe ich nextProps nicht verwendet.

Ich musste die _getData Methode ändern, um eine Variable zu nehmen und nextProps und nicht die aktuelle Requisite zu übergeben.

_getData(option){ 
     socket.emit('get_data', option); 
    } 


    componentDidMount() { 
     this._getData(this.props.location.query.option); 
     this._receiveData(); 
    } 

     componentWillReceiveProps(nextProps){ 
    if (nextProps.location.query.option != this.props.location.query.option) { 
     this._getData(nextProps.location.query.option); 
     this._receiveData(); 
    } 
} 
Verwandte Themen