Dr Mouse Dr Mouse - 22 days ago 5
React JSX Question

Update ReactJS app using websocket

I am trying to do a supervision page for my customer, but I am struggling with updating a ReactJS app in real time. This supervision page can contains up to sixteen video flux, which can or cannot be in service at the same time.

When I generate my page with Django, I build an initial list stored in a JS variable :

var anims = {{list|safe}}


My ReactJS code for a single video flux is the following :

var ModelFlux = React.createClass({
displayName : "Flux player",
propTypes: {
animID: React.PropTypes.number.isRequired,
},
componentDidMount:function() {
//generating the player
},
render: function() {
var newDivId = 'iv' + this.props.animID;
return(
React.createElement('div',{className:'col-md-3 col-sm-6 col-xs-12'},
React.createElement('div', {id:"content"},
React.createElement('div',{id:newDivId,className:'smallPl'})
)
)
)
}
})


Then, I use the following to generate X flux:

var ModelFluxwithID = anims
.map(function(anim) {return React.createElement('div',{},React.createElement(ModelFlux,{key:anim.key,animID:anim.animID}))})


And finally, I call my app :

var App = React.createClass({
displayName : "React App",
render: function() {
return(
React.createElement('div',{className:'container'},
React.createElement('div',{className:'row'},ModelFluxwithID)
)
)
}
})

ReactDOM.render(
React.createElement(App),
document.getElementById('react-app')
)


It is working perfectly fine when the page is generated. But my customer doesn't want to load the page each time a flux is online/offline, so I monitor in real time the status of each flux with a websocket, which update anims :

ws = new WebSocket('xxxxxx');
ws.onmessage = function(event) {
// Update the anims variable
}


How can I proceed to update the app when anims is changing (creating/destroying) ?

Answer

You need to keep the anim variable as state within the App class, and map your ModelFlux instances from the state. Then when the anim state is updated, the relevant child components will be updated. For example,

var App = React.createClass({
  displayName : "React App",
  render: function() {
    return(
        React.createElement('div',{className:'container'},
            React.createElement('div',{className:'row'},{this.mapAnims(this.state.anims)})
        )
    )
  },
  getInitialState: function() {
    return {
      anims: yourAnimsVariable
    };
  },
  updateAnims: function(newAnims) {
    this.setState({
      anims: newAnims
    });
  },
  mapAnims: function() {
    return this.state.anims.map(function(anim) {
       return React.createElement('div',{},React.createElement(ModelFlux,{key:anim.key,animID:anim.animID});
    }
  },
  componentWillMount: function() {
    var ws = new WebSocket('xxxxxx');
    ws.onmessage = function(event) {
        this.updateAnims(event.data.anims); //or wherever your new anim data is in the event    
    }
  }
});

ReactDOM.render(
  React.createElement(App),
  document.getElementById('react-app')
)