[译] 理解 React Render Props 和 HOC

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

内容简介:如果你最近有在做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》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

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

HTTP

HTTP

David Gourley、Brian Totty、Marjorie Sayer、Anshu Aggarwal、Sailu Reddy / O'Reilly Media / 2002-10-7 / USD 54.99

Product Description Web technology has become the foundation for all sorts of critical networked applications and far-reaching methods of data exchange, and beneath it all is a fundamental protocol......一起来看看 《HTTP》 这本书的介绍吧!

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

多种字符组合密码

SHA 加密
SHA 加密

SHA 加密工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具