【问题标题】:what is the responsibility of the container component in react+reduxreact+redux中容器组件的职责是什么
【发布时间】:2018-07-04 12:27:56
【问题描述】:

我是react redux的新手,它有一个“容器组件”的概念,和react中的“容器组件”是一样的,关注的是事情是如何工作的。在 redux 中,容器组件用于从 store 中访问 state,以避免将 props 向下传递给太多嵌套的子组件。

以下是我的问题:

(1) 容器组件是否负责组织业务逻辑?

(2) 有很多帖子,比如Where do I put my business logic in a React-Redux application?,都提到了把逻辑放到reducor/action creator/thunk 等等,但是没说容器组件,是不是漏掉了什么重要的东西?

【问题讨论】:

    标签: reactjs react-redux


    【解决方案1】:

    1) 不,业务逻辑应该保存在中间件、reducers 和 selectors 中。

    2) 容器组件实际上是由 connect HOC 创建的每个组件(与存储连接的所有内容)。如第 1 点所述,它不是业务逻辑的地方。


    更多关于 Redux 架构的答案

    当使用 Redux 时,container->presentation 组件的约定并不是真正需要的。您应该专注于将组件与商店直接连接起来。因此,您应该专注于直接交付所需的数据,而不是选择哪些组件是连接的,是容器,哪些不是,是呈现的。

    首选是避免从父组件传递 props 并在没有其他方法的情况下使用它。避免传递 props 的一个例子是 List -> Element components 关系。在使用容器组件的方法中,存储将连接到List(container),List 会将所有数据传递给每个Element(presentation) 组件。在没有container->presentation 的方法中,您将只向Element 组件发送id,而Element 组件将连接到商店,以获取强制属性。所以这里发送props减少到最低限度,而且由于两个组件都连接到store,你在container->presentation上是无法区分的。


    关于非 redux 架构的附加通知

    如果应用没有像redux这样的状态管理工具,那么使用container->presentation组件的方式是非常合理的。这是因为业务逻辑只保留在程序的一部分中,我的意思是容器组件,而表示组件可以是纯的和无状态的。感谢container->presentation 分割应用程序在状态修改和状态纯度之间有明确的分离。

    【讨论】:

    • 感谢 Maciej,这听起来很有道理。使用redux,它避免了将props传递给表示组件,HOC容器,理论上由connect返回,就像没有redux的容器一样,为什么不把逻辑放到mapDispatchToProps上,让容器的内聚性更高呢?好像redux里的container只是用来连接store的吧?
    • @RonSmith 您将逻辑放在减速器中,这将消耗您调度的操作。您在 mapStateToProps 中使用选择器,您还可以在其中放置一些商店选择逻辑。您放入像 saga 这样的中间件中的异步逻辑。组件本身应该只有视图逻辑而不是业务逻辑。而且你不应该在组件和商店之间有凝聚力,组件不应该知道商店并且它的道具是由redux传递的,组件不知道是谁提供了道具。这为几乎所有时间都提供功能组件提供了可能性。
    • 我只是认为reducer应该很简单地返回状态来更新状态,它不应该在里面做很多复杂的事情,还有一些边缘情况它可能应该访问其他声明的一些属性减速器。在减速器中也变得不可能。如果将其他操作分派给其他减速器怎么办?我认为逻辑业务将面临更多问题。
    • reducer 不需要简单,但在大多数情况下它很简单,因为您应该在许多 reducer 上具有解耦状态以覆盖它的一小部分。 Reducer 不需要检查其他 reducer 的属性,因为它可以访问您提供给它的 store 的一部分。许多减速器也可以消耗一个动作,它们之间的通信是不可能的并且是反对通量的。 Reducer 不会调度动作,但中间件会,在中间件中您可以一次运行许多动作。所以是的,存在边缘情况,但在这种方法中都是可行的
    • 其实reducer只关注状态逻辑,对吧?根据action参数做某事改变状态。但是比如validation和asyn request我们应该放到action creator或者中间件里面?
    【解决方案2】:

    一般做法

    container 组件指定presentational 组件应呈现的数据。容器组件还指定行为。如果展示组件有任何交互性——比如一个按钮——它会调用container 组件给它的prop-function。 container 组件是向Redux store 发送操作的组件。容器组件还可以访问 Redux 存储中的数据

    presentational 组件是只呈现 HTML 的组件。该组件的唯一功能是表示性标记。在 Redux 驱动的应用中,展示组件不与 Redux 存储交互。

    这是@DanAbramov 在this关于容器组件的文章中提到的一些要点

    1. 关心事物的运作方式。

    2. 内部可能同时包含展示组件和容器组件**,但通常没有任何自己的 DOM 标记,除了一些 包装 div,并且永远不会有任何样式。

    3. 向展示或其他容器组件提供数据和行为。

    4. 调用 Flux 操作并将这些操作作为回调提供给演示组件。

    5. 通常是有状态的,因为它们往往用作数据源。

    6. 通常使用高阶组件生成,例如 React Redux 的 connect()、Relay 的 createContainer() 或 Container.create() 来自 Flux Utils,而不是手写。

    【讨论】:

    • 非常感谢。正如你所说,容器组件只是将数据道具和回调函数发布到展示组件,并在回调中与 store 通信。所以我们不应该在容器中做验证等业务逻辑,而是放在action creator中?
    • 验证应该是容器的一部分,容器是包含你所有逻辑的容器,只有当你想更新存储中的数据或API请求时才应该使用动作创建者跨度>
    • 我同意你的观点,但是因为我们使用 mapStateToProps 和 mapDispatchToProps 创建容器,我们无法在 mapDispatchToProps 函数中访问状态,所以有时我必须将逻辑放在动作创建者中以便轻松访问状态。这会导致逻辑混乱,您对这种情况有什么建议吗?
    • 为什么要将状态访问到 mapDispatchToProps 函数中,动作创建者将是您将从容器组件中调用的东西,并且可以通过 mapStateToProps 访问存储
    • 假设在展示组件中点击一个按钮后,我想做一些计算,哪些应该从状态中访问一些数据,然后派出一个动作来改变状态,像这样,逻辑可以是在容器中。我不知道解决这种情况的正确方法是什么。目前我将回调传递给动作创建者并将状态传递回容器。你有更好的解决方案吗?
    猜你喜欢
    • 2016-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-13
    • 1970-01-01
    • 1970-01-01
    • 2017-07-29
    相关资源
    最近更新 更多