如何与Redux沟通React组件之间的UI状态变化

How to communicate UI state changes between React components with Redux?

本文关键字:之间 UI 状态 变化 组件 React Redux 沟通      更新时间:2023-09-26

就我对Redux的理解而言,它是将UI的所有状态保存在一个存储中(以便能够轻松地再现某些状态,并且没有副作用)。您可以通过触发减速器的触发操作来操纵状态。

我目前正在写一个类似博客的小应用程序,你可以简单地创建和编辑帖子。我有一个创建帖子的对话框,大致上App组件的render方法返回如下内容:

<div>
    <AppBar ... />
    <PostFormDialog
      addPost={actions.addPost}
      ref="postFormDialog" />
    <PostList
      posts={posts}
      actions={actions} />
</div>

我的问题是:对话框的状态(打开或关闭)应该是应用程序组件的状态对象的一部分吗?因此,是否应该通过一个动作触发打开和关闭对话框,而不是执行以下操作:

onTriggerCreatePostDialog(e) {
    this.refs.postFormDialog.show();
}

其中onTriggerCreatePostDialog是通过"创建"按钮上的某个点击监听器触发的。

对我来说,通过动作来做这件事似乎有点奇怪,因为它引入了一种"间接"。

但是,假设我想为编辑操作重用对话框,我必须能够从组件结构中更深的元素打开对话框,例如从PostList组件的子级Post组件打开对话框。我可以做的是通过props属性将onTriggerCreatePostDialog函数向下传递到层次结构中,但这对我来说似乎很麻烦…

因此,int的结尾也是关于不处于直接父子关系中的组件之间的通信。还有其他选择吗?我应该以某种方式使用全球活动巴士吗?我现在很不确定。

在我看来,你走的是正确的道路。文档一开始可能有点棘手,但我可以告诉你我和我的团队是如何使用实现的。

回答你的第一个问题;如果状态是特定于某个组件的,那么我们将该状态保留在该组件中。这方面的一个例子是一个在本地分页记录的面板——不需要其他人知道这种行为。因此,在这种情况下,当页面更改时,我们不会触发redux操作,这将在组件结构内部使用refs进行处理。

我们的redux状态主要由通过xhr请求或共享状态收集的数据组成。共享状态的一个示例是管理使用该范围来显示数据的多个组件之间的时间范围。在这种情况下,我们将触发一个redux操作;用更改后的状态更新日期状态(同时通过xhr更新一些其他状态项),然后最终返回到组件并重新渲染。

话虽如此,通过refs触发操作是完全可以接受的,这只是关于具体用例是什么

回答你的第二个问题;redux建议使用Smart&哑铃组件概念。因此,您将向树下传递一个函数以供哑组件使用,这是正确的。

我们在连接设置中使用mapDispatchToProps。所以基本上,您传递一个函数,该函数返回一个函数"dispatchers"的对象。您将能够直接在智能组件的this.props中访问这些功能。

mapDispatchToProps 示例

function mapDispatchToProps(dispatch) {
  return {
    myAction: () => dispatch(actions.myAction()),
  };
}

因此,这在99%的情况下都有效,但我遇到过一些情况,我们确实使用了全局事件总线,所以在尝试尽可能坚持Smart/Dumb组件方法的同时,不要害怕同时使用这两种方法。

顺便说一句,我建议使用reselect将您的redux状态映射到智能组件。你也可以在这里找到其他很棒的redux资源(这里列出了我们使用的几种东西)。

对话框的状态应该在redux存储中,由操作触发。是否应该呈现它应该通过检查redux存储中的状态来确定。

App.render()应该是这样的:

render() {
  const { showDialog } = this.props;
  return (
    <div>
      <AppBar ... />
      { showDialog ? <PostFormDialog ... /> : false }
      <PostList ... />
    </div>
  );
}

其中mapStateToProps将类似于state => {{ showDialog: state.showDialog }}

就交付动作创作者而言,将其传递到道具树可能是正确的方法,除非你有一个好的位置,在那里有另一个智能组件是有意义的。