React-Redux 设计模式:"deep" 组件应该连接到 Redux,还是从 parent 组件接收道具?

React-Redux design pattenrs: Should a "deep" component be wired to Redux, or receive props from parent components?

我正在构建一些在前端使用 React 和 Redux 的即时消息应用程序。我有 "Main"(初始化网络套接字并呈现其他组件)、"Chat"、"FriendsList" 和 "Friend"

等组件

我经常发现自己在想,我是否应该将 child 或 grandchild 直接连接到 Redux(假设它需要它),或者从 parent/grandparent.

例如,我在主组件中渲染 "Chat" 是这样的:

 <Chat
    onTyping={this.onTyping}
    onSubmitMessage={(value) => { this.submitMessage(value) }}
    messages={this.props.messages[this.props.activeFriend] || []}//This comes from Redux
    isMessagingAvailable={this.isMessagingAvailable()}    
  /> 

如您所见,我传递了一个 "messages" 道具,它又来自 Redux。我当然可以单独将 Chat 连接到 Redux。

那么问题是,在这种情况下是否有关于最佳实践的约定。 每个使用全局状态的组件都应该直接连接到 Redux 吗?

TL;DR;

模块化设计背后的理念是拥有尽可能多的通用组件。

这些组件应该独立于外部世界(即 Redux Store)。

以我的理解,任何应用程序的结构都应该是这样的:

  • 您有满足其目的的根级组件。喜欢:input box
  • 然后你有一个复合组件,它将使用这些根组件。就像处理错误标签和输入一样。
  • 然后你就形成了高阶组件(HOCs)。这些是业务组件,并且具有正在发生的事情的上下文。这些组件应该可以访问 Redux 存储。

示例:

让我们创建一个包含基本信息的表单:

  • 名字
  • 姓氏
  • 年龄
  • 电子邮件

对于这样的表单,您需要以下组件:

  • 文本输入组件
  • 带有文本 prevention/validation 逻辑的数字输入组件。

您可以将 textInput 用于 FirstNamelastNameemail。所以如果你直接把它绑定到 store,你就是在让它依赖于你自己的 redux 结构。所以这些组件不能在其他任何地方使用。

因此,最好的想法是创建能够接受 props 并执行其任务的哑组件。


您的用例。

您有以下模块:

  • 主要
  • 聊天
  • 好友列表
  • 朋友

将来,您打算再添加几个模块:

  • 人工智能/机器人聊天
  • 群聊

现在个人、机器人和群聊的聊天 window 会很相似,但商店结构会很困难。尤其是群聊。

那么你如何决定哪个组件应该绑定到存储?

您应该为您的视图创建嵌套组件层次结构,并为您的业务模块创建 HOC。这样,您的视图组件不依赖于商店。您的 HOC 将提供数据,仅此而已。

因此,在您的情况下,您将拥有以下 HOC:

  • 直接聊天
  • 机器人聊天
  • 群聊
  • 联系人
  • 仪表板

您可以拥有以下视图组件:

  • 聊天组件:用于所有聊天类型。
  • 联系人组件:用于好友列表/联系人视图
  • 列表组件:用于浏览器联系人、添加成员视图和管理成员视图。

恕我直言,这真的要视情况而定:

1) 如果 Child 组件独立使用数据,它总是从全局状态树的同一个分支获取数据:我会将它连接到 Redux。

  • 一个总是从state.tasks

  • 获取任务列表的任务列表组件
  • 一个 CurrentUserDetail 组件,它总是从 state.currentUser

  • 获取用户信息

2) 如果子组件根据其父组件使用数据:我会通过道具从父组件获取数据。或者听从父级如何从全局状态中获取数据,然后将其连接到 Redux 并获取相应的数据:

  • 一个 Task 组件,它从其父 TaskList 组件获取每个任务的任务数据

  • 一个TaskList组件,从它的parent获取taskListID,然后获取对应的任务列表。例如:taskListID="Martin" -> state.tasks['Martin']