2016-04-15 13 views
8

ソケットの設定方法が問題であるかどうか、またはデータのレンダリングが正しくないリアクションでReactとSocket.io:初期データを取得することができますが、新しい投稿が入ったときにビューが更新されません

私のソケットでデータを正常に取得できますが、新しいデータがサーバーに送信されたときには更新されません。私の意図はReactの州が新しいデータを自動的にレンダリングすることです。ソケット接続のために常に生きています。ここで

は、サーバからメッセージを取得し、それらをレンダリング私のクライアントアプリです:

var Chat = React.createClass({ 
    getInitialState: function() { 
    return { 
     messages: null 
    } 
    }, 
    componentWillMount: function(){ 
    var self = this; 
    socket.emit('getMessages'); 
    socket.on('serverMessages', function (data) { 
     self.setState({messages: data}) 
    }); 
    }, 
    render: function() { 
    var messages = this.state.messages ? <MessageList messages={this.state.messages}/> : null 
    return (
     <div className="jumbotron"> 
     { messages } 
     <MessageForm submitMessage={this.submitMessage}/> 
     </div> 
    ); 
    } 
}); 

ここにデータを発する私のサーバーコードです念のために:

io.on('connection', function (socket) { 

    socket.on('getMessages', function (data) { 
    Message.find(function(err, messages){ 
     socket.emit('serverMessages', messages); 
    }) 
    }); 

}); 

答えて

3

サーバーにコードがあるだけで初期ソケットconnectionに発砲。

サーバー:

socket.on('getMessages', function (data) { 
    Message.find(function(err, messages){ 
    socket.emit('serverMessages', messages); 
    }) 
}); 

クライアント:命名規則に基づいて

var Chat = React.createClass({ 
    getInitialState: function() { 
    return { 
     messages: null 
    } 
    }, 
    componentWillMount: function(){ 
    var self = this; 
    socket.emit('getMessages'); 
    socket.on('serverMessages', function (data) { 
     self.setState({messages: data}) 
    }); 
    }, 
    render: function() { 
    var messages = this.state.messages ? <MessageList messages={this.state.messages}/> : null 
    return (
     <div className="jumbotron"> 
     { messages } 
     </div> 
    ); 
    } 
}); 

、またあなたのMessage.find()は、単一のメッセージを引っ張っていることが表示されます。カーディナリティと一致するようにラベルを明確にすることをお勧めします。

+0

コードは急いでブラウザで書かれ、テストされていないため、誤植やロジックエラーがある場合はお詫び申し上げます。元の例の重要な欠陥は、 'getMessages'のためのイベントハンドラがありませんでした – kwcto

+0

ありがとう@kwcto - 私はあなたのフィードバックを実装しましたが、それは同じように動作します。新しいメッセージはページの更新時にのみ表示されます。 (私は新しい実装を反映するために質問を更新しました) – fresh5447

4

はこのお試しください:今のよう

var Chat = React.createClass({ 
    getInitialState: function() { 
    return { 
     messages: null 
    } 
    }, 
    componentWillMount: function(){ 
    var self = this; 
    socket.emit('getMessages'); 
    socket.on('serverMessages', function (data) { 
     self.setState({messages: data}) 
    }); 
    }, 
    render: function() { 
    var messages = this.state.messages ? <MessageList messages={this.state.messages}/> : null 
    return (
     <div className="jumbotron"> 
     { messages } 
     <MessageForm submitMessage={this.submitMessage}/> 
     </div> 
    ); 
    } 
}); 
4

をコンポーネントがロードされた後、あなたは「ただ」サーバーからデータをつかみました。あなたは定期的に指定した同じemitステートメントでサーバにpingを実行する(実際にはWebポケットを使用しない点で、長いポーリングを使用する)か、定期的にサーバを稼働させるすべてのクライアントに新しいデータを送信します。

あなたは行うことができますいずれか一方を

A)クライアント側:[理想的ではない]については、「ポーリング」

注:私はOPだった見たので、私は最初に私の答えでこれを入れコントローラがロードされたときの "ポーリング"。コントローラがwebsocketでロードされていない可能性がありますので、ここではクリックしていないので、connectでデータを送信するとここでは動作しない可能性があります。私の悪い。

setInterval(function() { 
    socket.emit('getMessages') 
}, 10000); /* Request data from the socket every 10 seconds */ 

OR

B)サーバー側は:それが利用可能になるように新しいデータを送信する "世論調査" データのための定期的WebSocketを何かで

置き換えsocket.emit('getMessages')。 [ベストウェイ]

クライアント配列を介してすべてのクライアントを追跡し、セッションが終了するとクライアント配列からそれらを削除します。データベース/データストレージから新しいメッセージをプッシュする必要があり

var clients = []; 

io.on('connection', function (socket) { 
    clients.push(socket); 

    socket.on('end', function() { 
     // Could also splice the array below, but it still works. 
     delete clients[clients.indexOf(socket)]; 
    }); 


    /* Previous logic for server goes here */ 
}); 

を実行し、このコード:

for (var i in clients) { 
    clients[i].emit('serverMessages', /* messages object */); 
} 
+0

オプションAについて:クライアント上でポーリングする必要はありません。サーバーソケットに接続されたクライアントソケットは、データのライブストリームを作成しません? – fresh5447

+0

オプションBが最善の方法です - 私はそれを言いましたが、明らかにそうではないと思いました。私は最初にポーリングしていましたが、websocketに接続したときにコンポーネントが読み込まれない場合には意味があります。P –

+0

ブロードキャスト/エミットを使用して名前空間やルームを使用する方が、クライアント( 'clients'配列)のトラック。複数のノードインスタンスの実行を開始すると、その 'clients'配列には、その特定のホストに接続されているインスタンスのみが含まれます。 socket.ioのデフォルトでは同じですが、複数のホストを扱う方法は正式に推奨されています。https://socket.io/docs/using-multiple-nodes/ – tybro0103

1

それはcomponentWillMountのライフサイクルメソッドにその原因可能だろうか?代わりにcomponentDidMountを試してみてください。

レンダリングは状態の更新を表示しますが、facebookに従った状態の変更にもかかわらず一度だけ実行されるようです。

関連する問題