[译] 理解 React Render Props 和 HOC

栏目: IOS · Android · 发布时间: 7年前

内容简介:如果你最近有在做React 开发,你肯定有遇到像 HOCs 和 Render Props 这样的术语。在本文中,我们将深入探讨这两种模式,以便了解我们为什么需要它们,以及如何正确地使用它们来构建更好的 React 应用。React 提供了一种简单的代码复用方式,即
[译] 理解 React Render Props 和 HOC

reactjs.org

如果你最近有在做React 开发,你肯定有遇到像 HOCs 和 Render Props 这样的术语。在本文中,我们将深入探讨这两种模式,以便了解我们为什么需要它们,以及如何正确地使用它们来构建更好的 React 应用。

为什么我们需要这些模式?

React 提供了一种简单的代码复用方式,即 组件 。组件封装了很多东西,包括内容、样式和业务逻辑。理想情况下,在单个组件中,我们可以将 html、css 和 js 结合起来,所有的这些是为了一个目的,单一职责。

提示:使用 Bit (Github) ,你可以组织和分享 可复用的组件 ,这些组件可以从不同的项目和应用中被发现,分享和开发。这比重写组件或者维护一个大型库要快得多。试试看 :)

例子

假设我们正在开发一个电子商务应用程序。它与其他电子商务应用程序一样,向用户显示所有可购买产品,并且用户可以将任何产品添加到购物车。我们将从 API 获取产品数据,并将产品目录显示为卡片列表。

在这种情况下,React 组件可以像这样实现:

[译] 理解 React Render Props 和 HOC

代码链接

对于我们的管理员,有一个管理门户,他们可以在其中添加或删除产品。在此门户中,我们从同一 API 获取产品数据,并以表格形式显示产品目录。

这个 React 组件可以像这样实现:

[译] 理解 React Render Props 和 HOC

代码链接

有一件事很明显,这两个组件都实现了产品的数据获取逻辑。

继续深入,以下这些情况也可能出现:

ProductList

如果我们为这些每一点都写个不同的组件,那么我们将要复制大量的代码。

获取数据和显示数据是两个独立的关注点。正如前面所说的,如果一个组件有一个责任会更好。

让我们重构第一个组件。它将接受产品数据为属性,并像之前一样把产品目录渲染成卡片列表。由于我们不需要 组件状态和生命周期方法 ,我们把它转换成函数式组件。

它现在看起来是这样的:

[译] 理解 React Render Props 和 HOC

ProductList.js (代码链接)

就像 ProductListProductTable 会是一个函数组件,它接收产品数据为属性,并把数据渲染到表的行中去。

现在让我们创建一个名为 ProductsData 的组件。它从 API 获取产品数据。数据的获取和状态的更新将和原先的 ProductList 组件一样。但是我们应该在这个组件的 render 方法中放入什么呢?

[译] 理解 React Render Props 和 HOC

ProductData.js (代码链接)

如果我们只是简单的放入 ProductList 组件,那么我们就不能复用这个组件于 ProductTable。不管怎样,如果这个组件可以询问要渲染什么,那个问题就会得到解决。在一个地方,我们将告诉它要渲染 ProductList 组件,而在管理门户中,我们告诉它要渲染 ProductTable 组件。

这就是 Render Props 和 HOCs 发挥作用的地方。它们只是一类方法,即对于一个组件,会询问应该渲染什么内容。这进一步推动了代码的复用。

现在我们知道了为什么需要它们,让我们来看看如何使用它们。

Render Props

在概念层面理解 Render Props 非常简单。让我们忘掉 React 一会,然后看看原生 JavaScript 下的事情。

我们有一个计算两个数字之和的函数。起初我们只想要把结果记录到控制台。所以,我们这样设计函数:

[译] 理解 React Render Props 和 HOC

但是,我们很快发现 sum 函数非常有用,我们需要在其他地方使用到它。因此,我们希望 sum 函数只提供结果,而不是将其记录到控制台,并让调用者决定如何使用结果。

它可以这么做:

[译] 理解 React Render Props 和 HOC

代码链接

我们传给 sum 函数一个 fn 回调函数作为参数。然后 sum 函数计算结果并把结果作为参数调用 fn 。通过这种方式,回调函数可以获得结果,并且可以自由地对结果进行任何操作。

这就是 Render Props 的本质。我们将通过使用这个模式来更清晰地认识它,所以让我们立刻把它用到我们现在面临的问题中去吧。

在这不是计算两个数字之和的函数,而是获取产品数据的组件 ProductsData 。现在可以通过属性传递给 ProductsData 组件一个函数。然后 ProductsData 组件将获取产品数据,并将这些数据提供给以属性方式传递进来的函数。传递进来的函数现在可以对产品数据做任何它想做的事情。

在 React 中,它可以像这样实现:

[译] 理解 React Render Props 和 HOC

代码链接

就像 fn 参数,我们有一个 render 属性,它将作为一个函数被传递。然后 ProductData 组件把产品数据作为参数调用这个函数。

因此我们可以以这种方式使用 ProductData 组件。

[译] 理解 React Render Props 和 HOC

代码链接

正如我们所看到的 Render Props 是一种相当通用的模式。大部分事情都可以非常直接地完成。但这也是我们搬起石头砸自己的脚的原因:

[译] 理解 React Render Props 和 HOC
[译] 理解 React Render Props 和 HOC
[译] 理解 React Render Props 和 HOC

避免嵌套的一种简单方法是把组件拆解成更小的组件,并将这些组件保存在单独的文件中。另一种方法是编写更多的组件并组合它们,而不是在 Render Props 中使用长函数。

接下来,我们将看下另一种流行的模式,它被称为 HOC。

高阶组件(HOC)

在这个模式中,我们定义了一个函数,该函数接受一个组件作为参数,然后返回相同的组件,但是添加了一些功能。

如果这听起来很熟悉,那是因为它类似于 Mobx 中广泛使用的装饰器模式。像 Python 这样的许多语言都内置了装饰器,JavaScript也很快就会支持装饰器。HOCs 很像装饰器。

比起用文字解释,用通过代码来理解 HOCs 会容易很多。所以让我们先来看代码。

[译] 理解 React Render Props 和 HOC

代码链接

正如我们所看到的,数据获取和状态更新逻辑就和我们在 Render Props 所做的一样。唯一的变化就是组件类是位于函数内部。该函数接受一个组件为参数,然后在内部的 render 方法中渲染这个组件,但是会添加额外的属性。对于名称如此复杂的模式,实现起来相当简单,对吧?

[译] 理解 React Render Props 和 HOC

代码链接

现在我们已经了解了为什么我们需要 Render Props,HOCs 以及我们如何实现它们。

还有一个问题:如何在 Render Props 和 HOCs 中进行选择?关于这个话题的文章已经有很多了,所以我现在不讨论这个话题。也许在我的下一篇文章中 :)

什么时候不要使用 Render Props — Kent C. Dodds

HOCs vs Render Props — Richard Kotze


以上所述就是小编给大家介绍的《[译] 理解 React Render Props 和 HOC》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Data Mining

Data Mining

Jiawei Han、Micheline Kamber、Jian Pei / Morgan Kaufmann / 2011-7-6 / USD 74.95

The increasing volume of data in modern business and science calls for more complex and sophisticated tools. Although advances in data mining technology have made extensive data collection much easier......一起来看看 《Data Mining》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

随机密码生成器
随机密码生成器

多种字符组合密码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具