【问题标题】:Update ReactJS app using websocket使用 websocket 更新 ReactJS 应用程序
【发布时间】:2016-11-17 15:47:05
【问题描述】:

我正在尝试为我的客户创建一个监督页面,但我正在努力实时更新 ReactJS 应用程序。此监督页面最多可以包含 16 个视频通量,它们可以或不能同时使用。

当我使用 Django 生成页面时,我会构建一个存储在 JS 变量中的初始列表:

var anims = {{list|safe}}

我的单个视频通量的 ReactJS 代码如下:

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'})
                )
            )
        )
    }
})

然后,我使用以下代码生成 X 通量:

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

最后,我调用了我的应用程序:

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')
)

生成页面时它工作得很好。但是我的客户不想在每次通量在线/离线时加载页面,所以我使用 websocket 实时监控每个通量的状态,更新 anims

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

动画发生变化(创建/销毁)时,我如何继续更新应用程序?

【问题讨论】:

    标签: javascript reactjs websocket


    【解决方案1】:

    您需要将 anim 变量作为状态保留在 App 类中,并从状态映射您的 ModelFlux 实例。然后当动画状态更新时,相关的子组件也会更新。例如,

    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 = 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')
    )
    

    【讨论】:

    • 感谢您的回答,这有助于我更多地了解我在做什么!我几乎让它工作了,但我仍然收到一条错误消息:this.updateAnims(event.data.anims);
    • 我把“this.data.anims”作为占位符放在那里。在 websockets onmessage 回调中,您需要使用已发送给您的任何数据来重新生成动画变量,然后调用 this.updateAnims 。从 websocket 返回什么数据?
    • 我使用 websocket 更新我的动画功能,添加或删除元素。
    【解决方案2】:

    基于 Alex Young 的回答和这个 SO 问题React this.setState is not a function,我终于成功了!最后一个技巧是在 ws.on 消息部分之前保存 App 引用!所以它给出了:

    componentWillMount: function() {
    var ws = new WebSocket('xxxxxx');
    var that = this; //
    ws.onmessage = function(event) {
        that.updateAnims(anims);
    }
    

    否则,this对应的是onmessage函数,而不是ReactJS App!

    【讨论】:

    • 哎呀我的错误,我已经编辑了我的原始答案以使用 ES6 lambda 函数来避免这种情况。
    猜你喜欢
    • 2017-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-04
    • 2013-06-21
    • 2011-09-10
    • 1970-01-01
    • 2020-04-04
    相关资源
    最近更新 更多