blog icon indicating copy to clipboard operation
blog copied to clipboard

React中的演示(UI)组件和容器组件

Open Hancoson opened this issue 6 years ago • 0 comments

React中的组件可以分为presentational components即UI(演示)组件和container components即容器组件。今天就来说说他们两个的区别以及这样的好处。

区别

我的演示组件:

  • 它只关心事物的样子。
  • 内部可以包含容器组件,通常有一些自己的DOM标记和样式。
  • 通常可以通过this.props.children进行控制。
  • 对应用程序的其余部分没有依赖关系,例如Fluxactionstores
  • 不需要指定数据的加载或变异。
  • 通过props接受和会掉数据。
  • 很少有自己的状态。
  • 被编写为功能组件,除非它们需要状态,生命周期或性能优化。
  • 示例:页面,边栏,故事,用户信息,列表。

我的容器组件:

  • 关心事情如何运作
  • 可能包含容器组件,但通常没有自己的任何DOM标记,除了一些包装div,并且没有任何样式。
  • 向演示组件或其他容器组件提供数据和行为。
  • 调用Flux/redux操作,并将其作为回调给演示组件。
  • 通常是有状态的,因为它们往往作为数据源。
  • 通常使用更高阶的组件(如来自Reat Reduxconnect()),来自RelaycreateContainer()或来自Flux UtilsContainer.create()生成的,而不是用手写。
  • 示例:UserPage,FollowersSidebar,StoryContainer,FollowedUserList。

好处

  • 更好的分离问题。通过以这种方式编写组件,您可以更好地理解您的应用程序和UI。
  • 更好的可重用性。您可以使用完全不同的状态源的相同的演示组件,并将其转换为可以进一步重复使用的单独的容器组件。
  • 演示组件本质上是您的应用程序的“调色板”。您可以将它们放在一个页面上,让设计师调整所有的变体,而不用触摸应用程序的逻辑。您可以在该页面上运行截图回归测试。
  • 这迫使您提取“布局组件”,例如Sidebar,Page,ContextMenu,并使用this.props.children,而不是在多个容器组件中复制相同的标记和布局。

记住,组件不必发出DOM。他们只需要在UI问题之间提供组合界限。

何时使用容器组件

我建议您开始构建您的应用程序的时候从UI组件开始。最终你会意识到,你正在把太多的props传给中间组件。当您注意到某些组件不使用他们收到的props,而只是转发它们,并且您必须在子组件需要更多数据时重新连接所有这些中间组件,这是引入一些容器组件的好时机。这样,您可以将数据和props到子组件,而不需要在不相关组件中负担。

这是一个持续的重构过程,所以不要开始就尝试。当您尝试使用此模式时,您将开始直观的了解何时抽出一些容器,就像您知道何时提取功能一样。

其他方法

重要的是,您明​​白UI组件和容器之间的区别不是一个技术性的。相反,它的目的是区别的。

相比之下,这里有一些相关(但不同的)技术区别:

  • 有状态和无状态的。一些组件使用React setState()方法,有些则不使用。虽然容器组件往往是有状态的,而且表示组件往往是无状态的,但这并不是一个难题。演示组件可以是有状态的,容器也可以是无状态的。
  • 类和函数。由于React 0.14,组件可以被声明为类和函数。功能组件更容易定义,但它们缺少当前仅适用于类组件的某些功能。其中一些限制可能会在将来消失,但今天存在。由于功能组件更易于理解,我建议您使用它们,除非您需要状态,生命周期或性能优化,这些类型组件此时才可用。
  • 纯净和不纯。人们说如果一个组件是纯粹的,如果它保证返回相同的结果给予相同的道具和状态。纯组件可以被定义为类和函数,并且可以是有状态的和无状态的。纯组件的另一个重要方面是它们不依赖于道具或状态中的深层突变,因此它们的渲染性能可以通过其shouldComponentUpdate()钩子中的浅层比较来优化。目前只有类可以定义shouldComponentUpdate(),但可能会在将来发生更改。

两个UI组件和容器都可以落入这些存储桶中。根据我的经验,UI组件往往是无状态的纯函数,容器往往是有状态的纯类。然而,这不是一个规则,而是一个观察,我已经看到与具体情况有关的恰恰相反的情况。

不要将UI和容器组件分离作为一个教条。有时候没有关系,也很难绘制线。如果您不确定特定组件是否应该是表示性的还是集装箱的,那么决定可能还为时过早。不要着急!

延伸阅读

Getting Started with Redux Mixins are Dead, Long Live Composition Container Components Atomic Web Design Building the Facebook News Feed with Relay

原文链接

Hancoson avatar Jul 23 '17 12:07 Hancoson