【问题标题】:Managing nested Redux containers without passing props?在不传递道具的情况下管理嵌套的 Redux 容器?
【发布时间】:2016-07-26 01:36:09
【问题描述】:

给定这样的组件层次结构:

<TodoList>
  <Todo>
    <TodoHeader/>
    <TodoBody>
      <TodoDetails>
        <TodoStatus />
      <TodoDetails>
      <TodoDescription />
    <TodoBody>
  <Todo>
</TodoList>

...还有这样的商店:

{
  todos: [
    { id: 1, status: "INCOMPLETE", header: "title one", description: "do a something" },
    { id: 2, status: "INCOMPLETE", header: "title two", description: "something else" },
    { id: 3, status: "COMPLETE", header: "title three", description: "one more thing" },
  ]
}

嵌套的TodoStatus组件有没有好办法连接到store,而不必向下传递id 组件层次结构作为道具?例如,Todo 可以将currentTodoId = 1 设置为上下文,这将是可用的 对于儿童减速机,但有替代品吗?也许是父组件将存储减少到的一种方法 然后子组件将能够看到的单个 todo...?

此时,您可能想问“为什么”?好吧,考虑在TodoList(对待办事项数组进行操作)和嵌套的TodoStatus(只想对单个待办事项进行操作)之间可能存在多个级别的严格表示组件。必须通过像这样的层次结构向下传递todoId 非常痛苦:

<TodoList>
  <Todo todoId={1}>
    <SomeAnimation todoId={1}>
      <SomeLayout todoId={1}>
        <SomeOtherAnimation todoId={1}>
          <SomeDebugContainer todoId={1}>
            <TodoHeader todoId={1}>
            <TodoBody todoId={1}>
              <TodoDetails todoId={1}>
                <TodoStatus todoId={1}> // yay!

在这一点上,我想象这正是 React 上下文的优势所在,因此可能没有特定于 Redux 的模式,但我想错了!

【问题讨论】:

    标签: javascript redux react-redux


    【解决方案1】:

    为什么他们都需要接受id 作为参数?

    通常层次结构中较高的某些组件(例如Todo)会接受idtodo,但下面的组件会更具体地说明它们接受的内容,例如

    function Todo({ todo }) {
      return (
         <SomeAnimation>
            <SomeLayout>
              <SomeOtherAnimation>
                <SomeDebugContainer>
                  <TodoHeader title={todo.title} />
                  <TodoBody {...todo} />
                </SomeDebugContainer>
              </SomeOtherAnimation>
            </SomeLayout>
         </SomeAnimation>
      )
    }
    

    在这个例子中,TodoHeader 只是直接接收一个title 属性。如果它需要更多道具,您可以像我在&lt;TodoBody&gt; 中那样使用{...todo} 分布todo 属性。从您的示例中并不清楚为什么像 SomeAnimation 这样的组件也需要知道待办事项 ID - 大概传递它的一些视觉属性就足够了。

    类似地,像 TodoBody 这样的内部组件可能会将它们的一些 props 向下传递,但同样,这不一定是 ID:

    function TodoBody({ title, text, status }) {
      return (
        <div>
          <TodoDetails text={text} />
          <TodoStatus status={status} />
        </div>
      )
    }
    

    一般来说,从render() 返回的深层树通常意味着您的组件结构不是最佳的。您不必在每个组件中都使用this.props.children——随意让组件控制自己的渲染,并且只传递必要的内容。有时传递id 很方便,有时直接传递数据会使依赖关系更加明确。

    【讨论】:

    • 谢谢!在这个例子中,我展示了所有中间组件都可用的完整 DOM,但我的意思是暗示父级(拥有todo)实际上并不直接访问深度嵌套的子级。例如,Todo 组件可能会简单地渲染 SomeAnimation 组件,然后它会渲染它自己的子组件等。在这种情况下,您需要一直向下传递 something等级制度; id 就是一个例子。我想知道是否还有其他模式可以很好地实现这一点。
    • 具体来说,在这种情况下(父级管理XYZ 对象的列表),因此您希望有一些组件为单个XYZ 逻辑执行表示逻辑。那么,对于父组件来说,能够减少各个组件可访问的状态树,这样他们就可以编写相对于那个单独的 XYZ 状态的化简器,这将是有用的。似乎这种行为可以通过一些 Redux 插件(如 redux-cursor)来访问,但我想知道是否存在我遗漏的现有模式。
    • 如果没有一个非常具体的例子,很难回答这个问题。也就是说 prop 传递在 React 中是绝对正常的,除非我们为每个组件讨论 > 10 个 props,否则我不太明白这个问题。
    • 很公平 - 道具传递确实有效,有时当它们不需要这些道具时,不得不“探查”其他组件(只是传递给嵌套的孩子)可能有点烦人.肯定有另一种选择,即使用context 使currentTodoId 之类的东西可用于嵌套reducer,但它看起来不像是内置在“核心”Redux 中的东西。这对我来说很好:)
    • 好吧,如果这真的是个问题,你可以把todoId放在上下文中。我不会推荐它。 :-)
    【解决方案2】:

    Connect 似乎是个坏主意,正如您所说,每个 Todo 都是一个演示组件,应该忽略有关 redux 存储或应用程序的任何内容。

    我在一个项目中遇到了同样的问题,目前我认为这似乎很痛苦,但它使每个元素都可重用并简化代码(不是代码数量而是逻辑)。也许你可以简化你的 dom/component 结构,使用 react children 封装来限制“级别”的数量

    不确定我帮了很多忙。如果你找到了一个很好的解决方案,我会很高兴阅读它。

    祝你好运

    【讨论】:

      猜你喜欢
      • 2017-09-03
      • 1970-01-01
      • 2021-03-08
      • 2012-10-04
      • 2018-03-12
      • 2015-08-14
      • 1970-01-01
      • 2020-09-13
      • 2018-10-17
      相关资源
      最近更新 更多