如何使用 Redux 在 React 组件之间传达 UI 状态更改?

IT技术 javascript reactjs redux
2021-05-03 13:44:39

据我了解,Redux 是将 UI 的所有状态保存在一个商店中(以便能够轻松重现某些状态并且没有副作用)。您可以通过触发减速器的触发操作来操纵状态。

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

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

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

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

whereonTriggerCreatePostDialog是通过“创建”按钮上的一些点击侦听器触发的。

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

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

因此,最终也是关于不在直接父子关系中的组件之间进行通信。还有其他选择吗?我应该以某种方式使用全局事件总线吗?我目前很不确定。

2个回答

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

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

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

话虽如此,通过 refs 触发操作是完全可以接受的,这只是关于特定用例的内容。

解决你的第二个问题;redux 建议使用Smart & Dumb组件概念。所以你是对的,你将一个函数向下传递给愚蠢的组件来使用。

我们在连接设置中使用 mapDispatchToProps 所以基本上你传递一个函数,它返回一个函数“调度程序”的对象。您将能够直接在智能组件的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 }}

就提供动作创建器而言,将其传递到props树可能是正确的方法,除非您有一些合适的位置可以让另一个智能组件有意义。