ReactJS + Flux - 如何实现 toasts/notifications?

Posted

技术标签:

【中文标题】ReactJS + Flux - 如何实现 toasts/notifications?【英文标题】:ReactJS + Flux - How to implement toasts/notifications? 【发布时间】:2015-06-21 11:29:46 【问题描述】:

我正在尝试理解 Flux 和 Reactjs。

考虑以下一个非常简单的场景:

您有一个输入很少的表单。当用户提交表单时,

ActionCreator.publishAnnouncement(this.state.announcement);

在我的表单组件中被调用。 这是 publishAnnouncement 方法的样子:

var publishAnnouncement = function (announcement) 
  AnnouncementAPI.publishAnnouncement(
    announcement,
    successCallback,
    failureCallback
  )
;

AnnouncementAPI 只是 AJAX http POST 调用的包装器。它需要两个回调——成功和失败。

现在:我需要在屏幕上显示通知/toast - 指示成功或失败。 你会如何以 Flux 的方式做到这一点?

我正在考虑创建通知组件并将其呈现在我的表单中。 像下面这样:

<Notification title=this.state.notification.title message=this.state.notification.title visible=this.state.notification.visibility  // ?? onTimeExceeded ??     />

但是我该如何处理这些回调呢?我应该创建 NotificationStore 来监听 ANNOUNCEMENT_PUBLISHING_SUCCEEDED 和 ANNOUNCEMENT_PUBLISHING_FAILED 事件吗?作为对这些事件的反应,store 会发出 CHANGE 事件,因此我的 Notification 会更新。

但即使我这样做了,我应该如何指示我的通知显示/隐藏?或者更糟糕的是,在 2 秒后出现并隐藏?

我在GitHub 上看到的组件很少,每个组件都使用 refs 等,我个人不喜欢这些。

总结一下: 您将如何实现这一点?或者这样的项目是否存在?如果有,我在哪里可以找到它?

【问题讨论】:

Facebook 自己在他们的 Flux 架构初始视频中谈到了使用 React 和 Flux 在 Facebook 中实现通知(用户消息)。 refs 是推荐的实现方式。对不起,你的性格需要改变;-) 但是 render 不应该是描述组件在某个时间点的状态的函数吗?如果是这样,那么使用这样一个带有 refs 的组件会完全破坏它。 @BenjaminGruenbaum 拥有用于用户通知的商店是有意义的。创建一个只是为了填充弹出组件状态 - 可能不是? 【参考方案1】:

我认为仅存储通知并没有什么问题,尤其是如果您想要在计时器上显示/隐藏通知、显示多个通知等逻辑时。

我会考虑用两种方式来写这篇文章:

    将 NotificationStore 直接绑定到您关心的成功/失败回调,就像您在问题中提到的那样。不确定您使用的是什么通量实现,所以这将是伪代码。

    class NotificationStore 
      constructor() 
        this.notificationId = 0;
        this.notifications = ;
        this.bindActionType(
          CLEAR_NOTIFICATION,
          this.handleClearNotification
        );
        this.bindActionType(
          ANNOUNCEMENT_PUBLISHING_SUCCEEDED,
          this.handleAnnouncementPublishingSucceeded
        );
        // etc...
      
    
      handleAnnouncementPublishingSucceeded(action) 
        this.addNotification("Success!",  timeout: 2000 );
      
    
      handleClearNotification(action) 
        this.removeNotification(action.notificationId);
      
    
      addNotification(message, options) 
        const nextId = this.notificationId++;
        const notification = 
          message: message
        ;
    
        this.notifications[nextId] = notification;
        this.emit("change");
    
        // if we specified a timeout, remove the notification
        // after the timeout expires.
        if (options.timeout) 
          setTimeout(() => 
            dispatch(CLEAR_NOTIFICATION, 
              notificationId: nextId
            );
          , options.timeout);
        
      
    
      removeNotification(notificationId) 
        delete this.notifications[nextId];
        this.emit("change");
      
    
    

    在您的动作创建者中指定您想要的通知。这更明确但不那么集中。

    var publishAnnouncement = function (announcement) 
      AnnouncementAPI.publishAnnouncement(
        announcement,
        (response) => 
          dispatch(ANNOUNCEMENT_PUBLISHING_SUCCEEDED, ...);
          dispatch(CREATE_NOTIFICATION, 
            message: "Success!",
            timeout: 2000
          );
        ,
        (error) => 
          dispatch(ANNOUNCEMENT_PUBLISHING_FAILED, ...);
          dispatch(CREATE_NOTIFICATION, 
            message: "Failure!"
          );
        
      )
    ;
    

    在这种情况下,NotificationStore 看起来基本相同,但没有绑定到每个成功/失败操作。无论哪种情况,我都会在组件树顶部附近有一个通知小部件,用于呈现通知列表。

【讨论】:

在我看来,第一个选项更干净。【参考方案2】:

为 refs 辩护(并且作为链接的 GitHub 存储库的作者):您的商店可以在它们更改时发出一个事件,该事件将在组件中具有一个处理程序。然后,此处理程序将通过 ref 触发通知。让你的组件通过 refs 而不是 props 处理通知要简单得多。

【讨论】:

以上是关于ReactJS + Flux - 如何实现 toasts/notifications?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Stores 管理 Flux/ReactJS 应用程序中的状态?

如何在 Flux / ReactJS 中处理多个相同类型的商店?

ReactJS 和 Flux 中的 $resource 对应项

reactjs/flux:按顺序执行动作(ajax)

ReactJS 嵌套列表 (flux)

具有 Flux 架构的 ReactJS 生成大型 JS 文件,最佳实践是啥?