2017-01-09 5 views
0

私はreactjsを学び、socket.ioを介してメッセージを受け取ったときにコンポーネントを更新する際に問題が発生しています。コンポーネントが最初に作成されたときに機能しますが、そのたびに、正しいデータを表示する前に2回呼び出す必要があります。reactjsライフサイクルメソッドでsocket.ioを使用

  1. たとえば、メニューボタンをクリックすると、コンポーネントはサーバーからデータを要求します。サーバーから結果が返され、コンポーネントが正しく表示されます。コンポーネントはゼロから作成されているため、完全に機能します。

  2. 別のメニューボタンをクリックしますが、コンポーネントはすでに上記のように作成されています。メニューボタンはサーバーからのデータを要求し、サーバーは結果を返しますが、コンポーネントはそれを更新して表示しません。ただし、別のメニューボタンをクリックすると、コンポーネントはサーバーによって送信された前の結果を表示します(コンポーネントは常にボタンを1回クリックします)。

なぜ私は意図していることをするために反応コンポーネントを取得する方法がわかりません(web devの非同期の性質のため)isntです。私はさまざまなライフサイクルの方法に疲れました。私の反応コードの一般的な改善を歓迎します。

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

コンストラクタであるcomponentDidMountとcomponentWillRecievePropsで_receiveDataを呼び出しています。私はcomponentDidMountで一度呼び出すことをお勧めします。あなたは1つに持っている2つのsetStateコマンドをマージすることもできます。それらを修正し、それがあなたの状況に役立つかどうかを確認してください –

+0

ありがとう。あなたの提案を含めるようにコードを編集しましたが、componentWillRecievePropsを使用するだけで、最初の作成後にコンポーネントが更新されなくなります。したがって、私はcomponentWillRecievePropsを使用して新しいボタンクリックに反応しようとしていました。 – Codematcha

答えて

0

私はついにそれを理解しました。 'componentWillReceiveProps(nextProps)'の実行中にnextPropsを使用していませんでした。

私は_getDataメソッドを変更して変数を取得し、現在のpropではなくnextPropsを渡す必要がありました。

_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(); 
    } 
} 
関連する問題