React 和 websocket - 数据操作

Posted

技术标签:

【中文标题】React 和 websocket - 数据操作【英文标题】:React and websocket - data manipulation 【发布时间】:2016-07-22 17:34:17 【问题描述】:

我正在尝试通过 websocket 实现与服务器的通信。 假设我不能使用 Flux 或类似的库。我的问题是更新服务器响应数据。

我不确定如何在服务器响应上实现回调函数以更新数据。

到目前为止,我有这样的东西(不是实际代码)

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

我希望示例能够清楚地说明我想要做什么以及我的问题是什么。这也使模型事件侦听器无法工作,除非它包含在我不太满意的反应组件之一中。

有没有更好的办法?

【问题讨论】:

好的...你的组件在哪里? 我没有添加组件,因为那不是我正在努力解决的部分。我的问题是关于如何在服务器响应上实现模型更新的数据流和最佳实践。我们可以说,在模型发出 viewAction 之后,组件按预期工作。 嗯,在不断变化的情况下,您的模型将被称为“商店”。组件侦听来自商店的更改事件以重新呈现其视图。最佳实践是让组件直接监听模型发出的事件,这就是为什么你应该包含一个示例组件。 另外,我想我们可能有不同的理念。从我的角度来看,我认为将模型包含在需要收听它的组件中没有任何问题。事实上,这对我来说似乎是唯一合理的方法,而这正是 Flux 的工作原理。数据是单向的,因为商店监听组件发出的 UI 事件,组件监听商店发出的更改事件。 我用组件示例更新了代码。我想再指出一次,模型-组件通信不是我的问题,而是处理服务器-模型数据流。像我这样的事件发射器是否实现了有效的解决方案。组件不是 store 而是 server 发出事件的一个。 【参考方案1】:

这里是flux architecture 的简单实现:

在您的情况下,您的操作来自 websocket 服务器响应,您的调度程序是 websocket,您的商店是模型。

进一步改进您的设计的几点:

让组件中的this.refresh 使用this.setState()model.get() 保存到其状态,以便它在内部调用重新渲染。 在您的组件中包含shouldComponentUpdate(),并将旧状态与当前状态进行比较,以确定组件是否真的需要更新。 这显着提高了应用程序的效率,减少了文档中的重排量 每当组件接收到 UI 事件时,如果该事件以任何方式影响应用程序状态,请通过 websocket 将事件发送回服务器,以便服务器可以发送刷新组件视图所需的任何更新。 (可选)如果模型能够在不与服务器通信的情况下从 UI 事件确定应用程序的状态,您可以改为将 UI 事件发送到模型,但请确保模型将该更改传播到侦听的组件它和服务器同步,这样它就不会与作为应用程序真实来源的服务器异步。

祝你写作顺利!

【讨论】:

以上是关于React 和 websocket - 数据操作的主要内容,如果未能解决你的问题,请参考以下文章

React-Native Websocket事件数据属性丢失

React.js & Flux - 在哪里注册 Websocket 事件(接收数据)的最佳位置

防止重复的 websocket 消息 Laravel Echo 和 React

React Native websocket event.data接收二进制数据时为空数组

使用 React / Websockets 渲染用户数

使用 React 管理多个 websocket