我使用Flux,React,我的组件是Simple和Messages:
jqXHR.done()
中调度结果。简单有一个更改监听器等待结果的发送。如果结果为null,我想使用我的Messages组件显示错误,因此我调用MessagesAction.addError('My result is null')
。当我收到null结果并立即调用Simple组件中的MessagesAction.addError
时,会出现问题。事实上,我知道这可能导致“在调度中间发送”错误,但我不知道如何重构这段代码以显示使用Flux的错误消息。
免责声明1 :我无法使用setTimeout
函数来解决此问题。这不是正确的解决方案。
免责声明2 :Simple
组件代表应用中将使用“消息”组件显示消息的任何其他组件。
简单代码:
findUser: function (value) {
UserAction.find(value);
},
componentDidMount: function () {
UserStore.addChangeListener(this.updateUser);
},
updateUser: function(){
var user = UserStore.getUser();
if (user == null){
MessagesAction.addError('My result is null!'); //here occur the error!
} else {
//set my user with setState
}
},
消息代码:
componentDidMount: function () {
MessagesStore.addChangeListener(this.addMessage);
},
addMessage: function () {
this.setState({
messages: MensagensStore.getMessages()
});
},
谢谢!
答案 0 :(得分:5)
嗯,问题是(至少在Facebook的Dispatcher实现中)你不能在商店回调中触发任何动作,这会导致不受欢迎/不可预测的行为,如无限调度或不一致的状态变化(例如竞争条件) 。这是由于单个广播调度员的性质。
IMHO最干净的解决方案(没有气味waitFor()
)是在触发组件中引入内部状态。使用状态可以在下一个更新周期中触发消息操作。这样,您就不会遇到未完成调度的问题。
// your component's implementation
getInitialState : function(){
return { user : undefined };
}
componentWillMount: function () {
UserStore.addChangeListener(this.updateUser);
},
componentWillUnmount: function () {
UserStore.removeChangeListener(this.updateUser);
},
componentDidUpdate : function(){
if(this.state.user == null){
MessagesAction.addError('My result is null!'); // no error anymore!
}
},
updateUser: function(){
this.setState({ user: UserStore.getUser(); });
},
答案 1 :(得分:4)
您的顶级容器应该监听UserStore和MessageStore上的更改。
MessageStore应该' waitFor' Userstore从UserStore导出它的状态(即更新它的消息属性)然后发出更改。
像这样:顶级UserContainer组件
findUser(value) {
UserAction.find(value);
}
componentDidMount () {
UserStore.addChangeListener(this.updateState);
MessageStore.addChangeListener(this.updateState);
}
updateState(){
this.setState({
user: UserStore.getUser(),
messages: MessageStore.getMessages()
});
}
renderMessages() {
if(!this.state.messages) return null;
return (
<Messages messages={messages} />
);
}
renderUser() {
if(!this.state.user) return null;
return (
<User {...this.state.user} />
);
}
render() {
return(
<div>
{this.renderMessages()}
{this.renderUser()}
</div>
);
}