TL; DR
这是我的一个视频,解释了(很差)这个问题:
https://www.youtube.com/watch?v=lJogEfYYHRo&feature=youtu.be
我正在使用flux在Web应用程序上创建聊天功能。 我有一个名为messages的数组商店。正如预期的那样,只要存储发生变化,商店就会发出更改事件,并且视图上的监听器会听到它并使用商店中的getter方法更新状态。
在这个应用程序中,我想加载一些初始消息(模仿从数据库中获取消息的历史记录)。但是,出于某种原因,每当我将视图上的状态设置为store getter(返回消息数组)时,只要将新消息推送到商店中的messages数组,它就会继续更新,这不应该是。它应该仅在广播变更事件时更新。为什么会这样?
这里的查看&所有相关代码
class ChatBar extends React.Component {
constructor(props) {
super(props);
// CHAT FUNCTIONS
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this._onChange = this._onChange.bind(this);
this.state = {
chat__messages: [],
chat__playercount: 0,
chat__message_input: "",
};
}
// ====================================================
componentDidMount(){
ChatStore.on(CHANGE, this._onChange);
ChatStore.init();
}
componentWillUnmount() {
ChatStore.removeListener(CHANGE);
}
_onChange() {
// IN THE FUTURE NEED TO CHANGE THIS TO
// RETURN ENTIRE STATE, NOT JUST MESSAGES
this.setState({chat__messages: ChatStore.getMessages()});
}
// HANDLING OF FORMS, DATA SUBMISSION ECT
// =====================================================
handleChange(e) {
this.setState({chat__message_input: e.target.value});
}
handleSubmit(e) {
e.preventDefault();
if (this.state.chat__message_input == "") {
// create some error here later
return
};
ChatActions.addMessage({
username: "username",
message: this.state.chat__message_input,
message_id: uid("msg-"),
});
// reset input field
this.setState({chat__message_input: ""});
}
...
这是商店
var CHANGE = "change_event";
class ChatStoreClass extends EventEmitter {
constructor() {
super();
this._messages = [
{
username: "christian",
message: "hello world",
message_id: "msg-12kjds8",
}
];
}
init() {
this._emitChange();
}
getMessages() {
return this._messages;
}
_emitChange() {
this.emit(CHANGE);
}
}
var ChatStore = new ChatStoreClass;
AppDispatcher.register(function(payload){
switch(payload.actionType) {
case ChatConstants.ADD_MESSAGE:
ChatStore._messages.push(payload.action);
break;
}
})
export default ChatStore;
ChatStore._messages.push(payload.action); 正在更新视图上的状态而不发出更改事件:(
道歉,如果说得不好。我通常不会向其他人解释我的编程问题,更不用说任何人了。
感谢您抽出宝贵时间阅读本文。
答案 0 :(得分:1)
getMessages()
正在将引用返回到商店中的邮件列表,而不是邮件本身。 SetState
(例如,在您的handleSubmit
中)始终触发对组件的更新;因为您已将this.state.chat__messages
设置为对商店消息列表的引用(而不是将其消息添加到您的chat_messages
数组中),所以它始终与商店保持同步。
getMessages() {
return [...this._messages]; // or w/o ES6 -> return Array.apply([], this._messages)
}
应该给你预期的效果。
我确信这是无意的,但部分困惑在于,除非通过SetState
,否则你永远不应该改变状态。通过使用对可变数据的引用,您可以获得意想不到的效果,这非常难以追踪。