我有一个应用程序,它使用react与flux和一个存储所有数据的web服务器,并在更新发生时通过websocket通知所有订阅者。
我的问题是,当我的组件触发一个动作的新状态被发送到web服务器通过套接字和存储在客户端浏览器,但然后我的服务器将发送一个消息给所有订阅者,这是这个组件的新状态,所以所有的客户端得到更新,但这导致客户端发送一个新的更新,状态已经改变。这是一个无限循环,客户端发送到服务器,服务器向所有订阅者响应更新,因为这是一个更新,客户端再次向服务器发送新状态…
跑龙套/WebAPI :
var socket = new SockJS("http://localhost:8080/stomp");
var client = Stomp.over(socket);
module.exports = {
sendUpdate: function(update){
if(client.connected){
client.send("/app/hello", {}, JSON.stringify(update));
}
},
getUpdates: function() {
client.connect({}, function() {
client.subscribe("/topic/hello", function(message) {
var data = JSON.parse(message.body);
MyActions.updateState(data.id, data.update)
});
});
}
};
MyActions :
var AppDispatcher = require('../dispatcher/AppDispatcher');
var FunctionConstants = require('../constants/FunctionConstants');
// Define actions object
var MyActions = {
updateState: function(id, update) {
AppDispatcher.handleAction({
actionType: FunctionConstants.STATE_UPDATED,
id: id,
update: update
})
}
};
module.exports = MyActions;
my store中的update函数:
var WebAPI = require('../utils/WebAPI');
var _ = require('underscore');
// Define initial data points
var _data = {};
function updateFunction(id, data) {
_data[id] = data
var update = "{"actionType": "STATE_UPDATED", "id": ""+id+"", "update": "+JSON.stringify(data)+"}";
WebAPI.sendUpdate(JSON.parse(update));
}
...
最后my component:
let React = require('react');
var MyActions = require('../../../actions/MyActions');
var WebAPI = require('../../../utils/WebAPI');
//Subscribe for updates sent from server
WebAPI.getUpdates();
let FunctionComponent = React.createClass({
newState: function(data){
MyActions.updateState(this.props.id, data);
},
render() {
var d = this.props.data;
d.count++;
return (
<div>
<h1>{this.props.id}</h1>
<div>{this.props.data}</div>
<button onClick={this.newState(d)}
</div>
)
}
});
module.exports = FunctionComponent;
当我的组件调用任何操作并且服务器向所有订阅者发送更新时,我如何克服导致无限循环的问题?
webapi . getuupdates ();应该在商店里,而不是部件里。以下是使用回流的基本储存方法。看看这个;Flux: waitFor specific event.
import Reflux from 'reflux';
import Actions from './Actions';
import AddonStore from './Addon.Store';
import MixinStoreObject from './Mixin.Store';
let BasicStoreObject = {
init() { this.listenTo(AddonStore, this.onAddonTrigger); },
data1: {},
listenables: Actions,
mixins: [MixinStoreObject],
onGotData1(data) { this.data1 = data; BasicStore.trigger('data1'); },
onAddonTrigger() { BasicStore.trigger('data2'); },
getData1() { return this.data1; },
getData2() { return AddonStore.data2; },
getData3() { return this.data3; }
}
const BasicStore = Reflux.createStore(BasicStoreObject);
export default BasicStore;