user3454914
user3454914

Reputation: 55

React and websocket - data manipulation

I am trying to implement communication with server through websocket. Let's say that I can't use Flux or similar libraries. My problem is updating data on server response.

I am not sure how to implement callback functions on server response to update data.

So far I have something like this(not an actual code)

events.js

const e = require('event-emitter');
var events = e();
module.exports = events;

socket.js

const events = require('./events');

module.exports = {
  var ws;

  init: function(URL) {
    ws = new WebSocket(URL);
    ws.onopen = function() { ... }
    ws.onclose = function() { ... }
    ws.onmessage = function(data) {
      events.emit(data.action, data);
    }

  },

  send: function(data) {
    ws.send(data);
  }
}

model.js

const events = require('./events')
var data = [];

/* listening for some specific event from socket */
events.on("action", doAction);

function doAction(data) {
  events.push(data);

  /* now I have to emit event which react component
  is listening to so it can update data */
  events.emit("viewAction");
  }
}

/* what react component uses to get and render data */
module.exports = {
  get: () => data,
  events: events
}

component.js

const React = require('react');
const ReactDOM = require('react-dom')
const model = require('./model');

var App = React.createClass({
  componentDidMount: function() {
    model.events.on('viewAction', this.refresh);
  },

  componentWillUnmount: function() {
    model.events.off('viewAction', this.refresh);
  }

  render: function() {
    return (
      <div>
        {model.get()}
      </div>
    )
  }
}

ReactDOM.render(
  <App />,
  document.getElementById('app')
);

I hope sample makes it clear what I am trying to do and what my problem is. This also makes model event listener not work unless it is included in one of the react components which I am not too happy about.

Is there a better way?

Upvotes: 3

Views: 1737

Answers (1)

Patrick Roberts
Patrick Roberts

Reputation: 51826

What you have here is a simplistic implementation of the flux architecture:

flux diagram

In your case, your action comes from a websocket server response, your dispatcher is the websocket, and your store is the model.

A couple of points to improve your design further:

  • Have this.refresh in the component save model.get() to its state using this.setState() so that it internally invokes re-rendering.
  • Include shouldComponentUpdate() in your component, and compare the old state to the current one in order to determine whether the component really needs to update. This improves the efficiency of your application dramatically, reducing the amount of reflows in your document
  • Whenever the component receives a UI event, if that event affects the application state in any way, send an event via the websocket back to the server so that the server can send any updates needed to refresh the components views.
    • Optionally, you can instead emit the UI event to the model if the model is able to determine the state of your application from the UI event without communicating with the server, but make sure the model propagates that change to the components listening to it, and to the server so that it doesn't desync from the server which is your application's source of truth.

Good luck on whatever you're writing!

Upvotes: 1

Related Questions