React 和 Flux:“在调度中间调度”以显示来自 API 调用的错误消息

Posted

技术标签:

【中文标题】React 和 Flux:“在调度中间调度”以显示来自 API 调用的错误消息【英文标题】:React and Flux: "dispatch in the middle of a dispatch" to show error message from an API call 【发布时间】:2016-06-23 20:26:27 【问题描述】:

我使用 Flux、React 并且我有组件 Simple 和 Messages:

Simple:它是一个通过Action调用API的简单组件。 Action 执行一个 ajax 请求并将结果发送到jqXHR.done()。简单有一个更改侦听器来等待结果的调度。如果结果为 null,我想使用我的 Messages 组件显示错误,所以我调用我的MessagesAction.addError('My result is null')消息:显示应用程序错误的组件。该组件有一个更改侦听器,等待显示新消息。它位于我的应用程序的标题中。

当我收到 null 结果并立即在 Simple 组件中调用 MessagesAction.addError 时会出现问题。事实上,我知道这会导致“Dispatch in the middle of a dispatch”错误,但我不知道如何重构这段代码以使用 Flux 显示错误消息。

免责声明 1:我无法使用 setTimeout 函数来解决此问题。这不是正确的解决方案。

免责声明 2Simple 组件代表应用程序中将使用 Messages 组件显示消息的任何其他组件。

简单代码:

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()
    );
,

谢谢!

【问题讨论】:

【参考方案1】:

好吧,问题在于(至少在 Facebook 的 Dispatcher 实现中)您不能在商店回调中触发任何操作,这会导致不希望/不可预测的行为,例如无限调度或不一致的状态更改(例如竞争条件) .这是由于单个广播调度程序的性质。

恕我直言,最干净的解决方案(不闻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(); );
,

【讨论】:

【参考方案2】:

您的***容器应该监听 UserStore 和 MessageStore 的变化。

MessageStore 应该“等待”UserStore,从 UserStore 派生它的状态(即更新它的 messages 属性),然后发出更改。

类似这样的东西:*** 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>
  );

【讨论】:

Simple 组件代表应用程序中的任何其他组件,它们也将使用 Messages 组件显示消息。很多组件,在不同的情况下,都需要显示一条消息。 在这种情况下,“消息”组件应该是一个智能组件,并监听消息存储本身的变化......然后您应该做的就是在您希望消息显示的任何位置呈现组件并它将处理它们的显示。希望有帮助 是的,他已经在监听存储 (MessagesStore) 以获取 MessageAction 为其他组件添加的新消息。但是当我这样做时,会出现我相关的问题。

以上是关于React 和 Flux:“在调度中间调度”以显示来自 API 调用的错误消息的主要内容,如果未能解决你的问题,请参考以下文章

Flux/Alt Basic 异步示例抛出“无法在调度中间调度”

如何协调 Flux 和 React 之间的服务器错误消息?

如何协调 Flux 和 React 之间的服务器错误消息?

在 React 组件中设置初始状态以进行渐进式增强和 Flux 架构

使用带有 Flux 的 React Router 以编程方式重定向

画布库如何适应 Flux 模式和 React?