Skip to the content.

展示型和容器型组件

原文

Dan Abramov

2015 年 3 月 23 日 - 阅读时间大约 5 分钟

2019 年的更新:我在很久以前写了这篇文章,后来我的观点发生了变化。尤其是,我不再建议像这样拆分你的组件了。如果你发现在你的代码库中这种方式很自然,这种模式可以很方便。但是我很多次发现这种模式被没有任何必要的强制实行,并且带有教条主义的狂热。我发现它有用的主要原因是它让我把复杂的有状态逻辑与组件的其他方面分开。自定义 Hooks 让我做同样的事情,不需要主观的划分。出于历史原因,这篇文章被保留下来,但不要太认真看待它。

在编写 React 应用程序时,我发现有一种简单的模式非常有用。如果你已经写了一段时间的 React,你可能已经发现了它。这篇文章很好地解释了它,但我想再补充几点。

如果你把组件分为两类,你会发现你的组件更容易被重用和理解。我称它们为容器型组件和展示型组件,但我也听说过胖子/瘦子、智慧/愚笨、有状态组件/纯组件、荧幕/组件等等。这些术语意思不完全相同,但核心思想是相似的。

我所认为的展示型组件。

我所认为的容器型组件。

这种模式的益处

请记住,组件并不一定需要返回 DOM。它们只需要在 UI 关注点之间提供组合边界。

利用好这个优势。

何时引入容器型组件?

我建议你在构建你的应用程序时,首先只使用展示性组件。最终你会意识到,你在中间组件中传递了太多的 props。当你注意到有些组件并不使用它们收到的 props,而只是将它们转发下去,并且当子组件们需要更多的数据时,你不得不重写那些中间组件时,这就是引入一些容器型组件的好时机。这样,你就可以把数据和行为 props 送到子组件上,而不会给树中间的无关组件带来负担。

这是一个不断重构的过程,所以不要试图在第一次就把它做好。当你尝试使用这种模式时,你会发展出一种直觉,知道什么时候该提取一些容器,就像你知道什么时候该提取一个函数一样。我的Redux Egghead 系列可能也会对你有所帮助!

其他二分法

重要的是你要明白,展示型组件和容器型组件之间的区别不是技术上的区别。相反,他们的区别在于目的上的区别。

相比之下,这里有几个相关(但不同!)的技术上的区别。

展示型组件和容器型都可以应用到这些二分法中。根据我的经验,展示型组件往往是无状态的纯函数组件,而容器型组件往往是有状态的类(class)组件。然而这不是一个规则,而是一种观察,我见过完全相反的情况,在特定情况下是有意义的。

不要把展示型和容器组件的分离当作教条。有时它并不重要,或者很难划清界限。如果你对某个特定的组件应该是展示型的还是容器性的感到不确定,现在决定可能还为时过早。不要紧张!

例子

这个 Michael Chan 写的片段很好的诠释了这种模式。

延伸阅读

脚注