React 和 Flux:"dispatch in the middle of a dispatch" 显示来自 API 调用的错误消息
React and Flux: "dispatch in the middle of a dispatch" to show error message from an API call
我正在使用 Flux、React 并且我有组件 Simple 和 Messages:
- Simple:它是一个通过 Action 调用 API 的简单组件。 Action 执行 ajax 请求并在
jqXHR.done()
中发送结果。简单的有一个变化监听器来等待结果的发送。如果结果为空,我想使用我的消息组件显示错误,所以我调用我的 MessagesAction.addError('My result is null')
.
- Messages:显示应用程序错误的组件。该组件有一个更改侦听器,等待显示新消息。它位于我的应用程序的 header 中。
问题发生在我收到空结果并立即调用 Simple 组件内的 MessagesAction.addError
时。事实上,我知道这会导致“Dispatch in the middle of a dispatch”错误,但我不知道如何重构此代码以使用 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()
});
},
谢谢!
您的顶级容器应该监听 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>
);
}
好吧,问题是(至少在 Facebook 的 Dispatcher 实现中)您不能在商店回调中触发任何操作,这会导致 undesired/unpredictable 行为,例如无限调度或不一致的状态更改 (例如竞争条件)。这是由于单个广播调度程序的性质。
恕我直言,最干净的解决方案(没有气味 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(); });
},
我正在使用 Flux、React 并且我有组件 Simple 和 Messages:
- Simple:它是一个通过 Action 调用 API 的简单组件。 Action 执行 ajax 请求并在
jqXHR.done()
中发送结果。简单的有一个变化监听器来等待结果的发送。如果结果为空,我想使用我的消息组件显示错误,所以我调用我的MessagesAction.addError('My result is null')
. - Messages:显示应用程序错误的组件。该组件有一个更改侦听器,等待显示新消息。它位于我的应用程序的 header 中。
问题发生在我收到空结果并立即调用 Simple 组件内的 MessagesAction.addError
时。事实上,我知道这会导致“Dispatch in the middle of a dispatch”错误,但我不知道如何重构此代码以使用 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()
});
},
谢谢!
您的顶级容器应该监听 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>
);
}
好吧,问题是(至少在 Facebook 的 Dispatcher 实现中)您不能在商店回调中触发任何操作,这会导致 undesired/unpredictable 行为,例如无限调度或不一致的状态更改 (例如竞争条件)。这是由于单个广播调度程序的性质。
恕我直言,最干净的解决方案(没有气味 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(); });
},