Logo
Section 1 / 7

高阶组件

学习高阶组件的工作原理以及如何创建它们。

导入

高阶组件

学习高阶组件的工作原理以及如何创建它们。

使用高阶组件进行重构

React 的强大之处在于它允许你将网页应用拆分为一个个独立的单元,称为组件。但如何将不同的功能分配给不同的组件,规则并不总是清晰明了。原则上,任何一个 React 应用都可以被写成一个单一的庞大组件;而从另一个极端来看,页面中的每一个 DOM 元素也可以由一个独立的微型组件来管理。

一个实用的经验法则是:每个组件应只负责一项任务。如果一个组件承担了多个职责,那么它就值得被拆分。这种区分是直观的,而非技术性的。没有任何自动化工具能告诉你某个组件是否具有多重职责。然而,以这样的思路思考,将有助于你在开发过程中保持代码的可维护性。组件越复杂,后续修改起来就越困难。

本章将介绍一种名为高阶组件(HOCs)的模式,用于将复杂的组件拆分为更简单的部分。你将在上一章的轮播组件基础上添加新功能,同时通过将部分逻辑提取到高阶组件中,使核心组件变得更简洁。此外,你还将学习如何使用 React Devtools 查看浏览器中不同组件之间的交互关系。

创建高阶组件

从抽象的角度看,高阶组件是指任何接收一个组件并返回另一个组件的函数。通常情况下,高阶组件返回的组件是一个对原始组件的包装,为其增加新的功能。下面是一个简单的例子:

1const BindProps = (Component, boundProps) => { // 1 2 const ComponentWithBoundProps = props => ( 3 <Component {...props} {...boundProps} /> // 2 4 ); 5 ComponentWithBoundProps.displayName = 6 `BindProps(${Component.displayName || Component.name})`; // 3 7 return ComponentWithBoundProps; 8}; 9 10const CarouselWithTestAttr = BindProps(Carousel, { // 4 11 'data-test-id': 'carousel', 12});
  1. BindProps 这个高阶组件接收两个参数:一个组件和一个要绑定到该组件的属性对象。
  2. 由于 boundProps 在传递时被放在 props 之后展开,因此 boundProps 的值会覆盖同名的 props。
  3. displayName 是 React 组件的一个特殊属性,用于在调试时显示组件名称。之前我们并未涉及此属性,因为 JavaScript 函数和类自带 name 属性,通常可以作为备用。但对于像这样动态生成的组件,必须手动设置名称。采用 "HOC(组件)" 这样的命名格式是一种常见惯例。
  4. 在这里,BindProps 被用来生成一个行为与 Carousel 完全相同的组件,但该组件始终会接收到 data-test-id="carousel" 这个属性。

使用 Styled-Components 在 JavaScript 中进行样式设计

创建高阶组件