为什么redux建议只连接到顶级组件?

时间:2015-12-11 00:22:15

标签: reactjs redux

我是redux和react-redux的新手,同时我正在努力制作一个redux应用程序。

我不理解redux文档中的声明:

  

然后,我们使用来自react-redux的connect()函数将我们想要连接到Redux的组件包装起来。尝试仅针对顶级组件或路由处理程序执行此操作。 虽然从技术上讲,您可以将应用中的任何组件()连接到Redux商店,但要避免这样做太深,因为这会使数据流更难以跟踪。

连接到所有组件是否更容易?当状态更新时,每个组件都可以获得新的状态树?

为什么哑组件和高级容器?

感谢。

5 个答案:

答案 0 :(得分:20)

如前所述,Abramov(Redux作者)已经回顾了他的建议:connect() ed组件。他在this Reddit post on the topic中阐述了一个很好的经验法则:

  

我是这样做的:

     
      
  1. 首先使用一个容器和几个表示组件

  2.   
  3. 随着演示组件树的增长,“中间”组件开始传递太多道具

  4.   
  5. 此时,我将一些叶子组件包装到容器中,以便“中间”组件不需要接受并传递与它们完全无关的道具

  6.   
  7. 重复
  8.         

    如果您观看我在Egghead课程中的最后十个视频,这正是我演示的方法:https://egghead.io/series/getting-started-with-redux

从我的阅读中,connect()的初步建议与性能无关,而与模块化组件和放大器无关。易于推理大型应用程序中的数据流。

事实上,更多connect() ed组件可能是性能优势,而1-container-to-rule-all-all-top-heavy模式。 Abramov once more

  

这两种方法都很好,并且嵌套的connect()组件实际上会为您提供更多性能。缺点是它们与应用程序的关联程度略高,而且稍微难以测试,但这可能不是一个大问题。

答案 1 :(得分:12)

当我在顶部有一个容器时,我遇到了效率问题,因为React在树中某处稍微更新时重新渲染了我的所有组件。所以我放弃了这种方法,并使我的应用程序反对文档,结果证明更快。

但后来我发现即使是Redux的作者也在他的Twitter上写道:

  

在Redux示例中强调“顶部的一个容器组件”是一个错误。不要把它当作格言。

https://twitter.com/dan_abramov/status/668585589609005056

  

尝试将您的演示文稿组件分开。通过在方便的时候连接它们来创建容器组件。   https://twitter.com/dan_abramov/status/668586001175048192

答案 2 :(得分:4)

本节的答案在您的文档摘录中:

  

虽然从技术上讲,您可以将应用中的任何组件()连接到Redux   存储,避免这样做太深,因为它会使数据流动   更难追查。

Redux的核心原则之一是数据通常应该从上到下流动,即它应该是单向的。如果connect下层组件太多,则您的数据流不再是单向的。 这样做的主要结果是,组件之间的状态更加容易。

当自上而下(当你只连接有限数量的高级组件时自然会发生这种情况),创建状态不一致的情况要困难得多,因此文档中的建议也是如此。

答案 3 :(得分:1)

在阅读我在此处发布答案时的最新答案时,我想进一步补充使用官方Redux style guide连接每个组件的共识:

建议让更多的UI组件订阅Redux存储并以更细粒度的级别读取数据。通常,这会带来更好的UI性能,因为在给定状态改变时需要呈现的组件更少。

例如,让<UserList>检索所有用户ID的列表,将列表项呈现为<UserList>,而不仅仅是连接<UserListItem userId={userId}>组件并读取整个用户数组,已连接<UserListItem>并从商店中提取其自己的用户条目。

这适用于React-Redux connect() API和useSelector()钩子。

答案 4 :(得分:0)

在某些情况下,您可以更深入地使用connect() ed组件。我不会如此严格地解释文档。

一般来说,如果你发现自己从组件传递了太多道具,那么传递的组件就不会使用这些道具,那么它们就可以移动到一个单独的容器组件中。 / p>

如果您发现自己经常在组件链中写道具,那么可能是时候添加容器了:

// A blog post view component
render () {
  const {post} = this.props;

  return (
    <div>
      <h1>{post.title}</h1>

      <Author author={this.props.author}
        onClick={this.props.favAuthor}
        onHover={this.props.authorDetails}
        isAuthorFaved={this.props.isAuthorFaved}
        isAuthorFollowed={this.props.isAuthorFollowed}/>
    </div>
  )
}

在这种情况下,帖子组件没有任何使用或需要用于<Author/>的任何道具。您可能需要考虑改为<AuthorContainer author={this.props.author}/>。作者属于这个帖子,所以你需要那些信息。其余的可以使用容器的mapStateToProps(state, ownProps)函数中的state来计算,其中ownProps.author是作者对象。

同样,这是一个人为的例子,但最终由逻辑属于你。