\
高阶组件(hoc)是 react 中一项有趣的技术,用于重构共享几乎相同逻辑的类似组件。我知道这听起来很抽象而且很高级。然而,它是一种并非特定于 react 的架构模式,因此您可以使用该方法来做很多事情。
例如,您可以使用它向某个组件添加加载指示器,而无需调整原始组件,或者您可以隐藏组件的属性以使其不那么冗长。应用程序有很多,我试图在本教程中介绍其中的大部分。
还有其他几个教程可以教您有关 HOC 的知识,但其中大多数都是针对高级 React 开发人员的。当我开始学习 React 时,我很难理解高阶组件的概念以及如何将 HOC 合并到我的项目中以编写更好的代码。本文将解释您需要了解的 HOC 从头到孵化的所有内容。
本教程分为三个部分。第一部分将介绍高阶组件的概念。在这里,我们将讨论在查看高阶函数和 HOC 之前需要了解的语法。第二部分是本系列中最令人兴奋的部分,您将看到 HOC 的实际示例。我们将使用 HOC 来创建表单、授权和许多其他事情。
在本教程的第三部分中,我们将更多地关注**实践以及实现高阶组件时需要考虑的事项。我们还将简要介绍 React 中代码共享的替代模式,例如 Render props。
在开始之前,**先看看有状态组件与无状态组件的教程,以便更好地理解 React 的组件架构。
我们很快就会动手。但在此之前,我认为您应该了解一些事情。我更喜欢尽可能使用 ES6 语法,它与 HOC 配合得很好。作为初学者,HOC 有意义,但某些 ES6 语法却没有意义。因此,我建议您先浏览一遍本节,稍后您可以再回来参考。
箭头函数是常规函数表达式,但语法较短。它们最适合非方法函数,这也是我们特别感兴趣的。以下是一些帮助您入门的示例:
/* Functions without parameters */
function () {
return "This is a function expression";
}
// is equivalent to
() => {
return "This is an arrow function expression"
}
// or
() => "Arrow with a shorter syntax"
/* Function with a single parameter */
function (param) {
return { title: "This function accepts a parameter and returns an object",
params: param}
}
// is syntax-equivalent to
param => {
return { title: "This arrow function accepts a single parameter",
params: param }
}
/* Function with multiple parameters */
function (param1, param2) {
return { title: "This function accepts multiple parameters",
params: [param1,param2]}
}
// is syntax-equivalent to
(param1, param2) => {
return {title: "Arrow function with multiple parameters",
params: [param1, param2]
}
}
// or
(param1, param2) => ({
title: "Arrow function with multiple parameters",
params: [param1, param2]
})
虽然这个名字暗示它与流行的印度美食中的一道异国菜肴有关,但事实并非如此。柯里化可帮助您将接受多个参数的函数分解为一系列一次接受一个参数的函数。这是一个例子:
//Usual sum function
const sum = (a, b) => a + b
//Curried sum function
const curriedSum = function (a) {
return function (b) {
return a+b
}
//Curried sum function using arrow syntax
const curriedSum = a => b => a+b
curriedSum(5)(4)
//9
该函数只接受一个参数,并返回一个接受另一个参数的函数,这种情况一直持续到满足所有参数为止。
curriedSum // (a) => (b) => a+b curriedSum(4) // (b) => 4+b curriedSum(4)(5) //4+5
一个密切相关的术语称为“部分应用”。部分应用程序通过预先填充现有函数的一些参数来创建新函数。新创建的函数的元数(即参数数量)将小于原始函数的元数。
扩展运算符扩展数组、字符串或对象表达式的内容。以下是您可以使用传播运算符执行的操作的列表
/*Spread Syntax in Function Calls */ const add = (x,y,z) => x+y+z const args = [1,2,3] add(...args) // 6
/* Spread in Array Literals */ const twoAndThree = ['two', 'three']; const numbers = ['one', ...twoAndThree, 'four', 'five']; // ["one", "two", "three", "four", "five"]
/* Spread in Object Literals */
const contactName = {
name: {
first: "Foo",
middle: "Lux",
last: "Bar"
}
}
const contactData = {
email: "fooluxbar@example.com",
phone: "1234567890"
}
const contact = {...contactName, ...contactData}
/* {
name: {
first: "Foo",
middle: "Lux",
last: "Bar"
}
email: "fooluxbar@example.com"
phone: "1234567890"
}
*/
我个人喜欢三个点可以让您更轻松地将现有道具传递给子组件或创建新道具的方式。
const ParentComponent = (props) => {
const newProps = { foo: 'default' };
return (
)
}
现在我们已经了解了构建 HOC 的基本 ES6 语法,让我们看看它们是什么。
什么是高阶函数?维基百科有一个简单的定义:
在数学和计算机科学中,高阶函数(也称为泛函、函数形式或函子)是一种接受一个或多个函数作为参数或返回一个函数作为其结果或两者兼而有之的函数。
您之前可能以某种形式在 JavaScript 中使用过高阶函数,因为这就是 JavaScript 的工作方式。将匿名函数或回调作为参数传递或返回另一个函数的函数 - 所有这些都属于高阶函数。下面的代码创建了一个本质上更高阶的计算器函数。
const calculator = (inputFunction) =>
(...args) => {
const resultValue = inputFunction(...args);
console.log(resultValue);
return resultValue;
}
const add = (...all) => {
return all.reduce( (a,b) => a+b,0) ;
}
const multiply = (...all) => {
return all.reduce((a,b)=> a*b,1);
}
让我们更深入地了解一下这一点。 calculator() 接受一个函数作为输入并返回另一个函数——这完全符合我们对高阶函数的定义。因为我们使用了剩余参数语法,所以返回的函数将其所有参数收集在一个数组中。
然后,使用传递的所有参数调用输入函数,并将输出记录到控制台。所以计算器是一个柯里化的高阶函数,你可以像这样使用计算器:
calculator(multiply)(2,4); // returns 8 calculator(add)(3,6,9,12,15,18); // returns 63
插入一个函数,例如 add() 或 multiply() 和任意数量的参数,以及 calculator()将从那里拿走它。所以计算器是一个扩展了 add() 和 multiply() 功能的容器。它使我们能够在更高或更抽象的层面上处理问题。乍一看,这种方法的好处包括:
代码可以在多个函数中重复使用。
您可以在容器级别添加所有算术运算通用的额外功能。
更具可读性,并且能更好地表达程序员的意图。
现在我们对高阶函数有了一个很好的了解,让我们看看高阶组件的能力。
高阶组件是一个接受组件作为参数并返回该组件的扩展版本的函数。
(InputComponent) => {
return ExtendedComponent
}
// or alternatively
InputComponent => ExtendedComponent
扩展组件 组成 InputComponent。 ExtendedComponent 就像一个容器。它呈现 InputComponent,但因为我们返回一个新组件,所以它添加了一个额外的抽象层。您可以使用此层添加状态、行为甚至样式。如果您愿意,您甚至可以决定根本不渲染 InputComponent — HOC 能够做到这一点以及更多。
下面的图片应该可以消除混乱(如果有的话)。
理论已经讲完了,让我们开始看代码。下面是一个非常简单的 HOC 示例,它将输入组件包装在
标记周围。从这里开始,我将把 InputComponent 称为 WrappedComponent,因为这是惯例。不过,您可以随意命名它。/* The `with` prefix for the function name is a naming convention.
You can name your function anything you want as long as it's meaningful
*/
const withGreyBg = WrappedComponent => class NewComponent extends Component {
const bgStyle = {
backgroundColor: 'grey',
};
render() {
return (
);
}
};
const SmallCardWithGreyBg = withGreyBg(SmallCard);
const BigCardWithGreyBg = withGreyBg(BigCard);
const HugeCardWithGreyBg = withGreyBg(HugeCard);
class CardsDemo extends Component {
render() {
}
}
withGreyBg 函数将一个组件作为输入并返回一个新组件。我们不是直接组合 Card 组件并将样式标签附加到每个单独的组件,而是创建一个 HOC 来实现此目的。高阶组件包装原始组件并在其周围添加
标签。需要注意的是,这里你必须手动将 props 分两层传递下去。我们没有做任何花哨的事情,但这就是正常的 HOC 的样子。下图更详细地演示了 withGreyBg() 示例。虽然这目前看起来不是特别有用,但好处并不小。考虑这种情况。您正在使用 React 路由器,并且需要保护某些路由 - 如果用户未经过身份验证,则对这些路由的所有请求都应重定向到 /login。我们可以使用 HOC 来有效管理受保护的路由,而不是重复身份验证代码。好奇想知道怎么做吗?我们将在下一个教程中介绍这一点以及更多内容。
注意:ECMAScript 中提出了一个称为装饰器的功能,可以轻松使用 HOC。但是,它仍然是一个实验性功能,因此我决定不在本教程中使用它。如果您使用的是 create-react-app,则需要先弹出才能使用装饰器。如果您运行的是**版本的 Babel (Babel 7),您所需要做的就是安装 babel-preset-stage-0 然后将其添加到 webpack.config.dev.js 的插件列表中,如下所示。
// Process JS with Babel.
{
test: /.(js|jsx|mjs)$/,
include: paths.appSrc,
loader: require.resolve('babel-loader'),
options: {
// This is a feature of `babel-loader` for webpack (not Babel itself).
// It enables caching results in ./node_modules/.cache/babel-loader/
// directory for faster rebuilds.
cacheDirectory: true,
presets: ['stage-0']
},
在本教程中,我们学习了 HOC 的基本概念。 HOC 是构建可重用组件的流行技术。我们首先讨论基本的 ES6 语法,以便您更容易习惯箭头函数并编写现代 JavaScript 代码。
然后我们了解了高阶函数及其工作原理。最后,我们接触了高阶组件并从头开始创建了 HOC。
接下来,我们将通过实际示例介绍不同的 HOC 技术。在那之前请继续关注。在评论部分分享你的想法。
以上就是React 中高阶组件的友好介绍的详细内容,更多请关注本网内其它相关文章!
** Windows 性能的**免费优化软件每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
下载 来源:php中文网 收藏
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn 作者**文章
C++ 中引用传递和指针传递的区别及优缺点分析 2024-09-23 11:21:02
现在还有人看涨以太坊吗? 2024-09-23 11:10:28
重载Java函数的**实践是什么? 2024-09-23 11:09:17
小米王腾晒 Redmi Note 14 Pro+ 真机,展示抗摔、防水性能 2024-09-23 11:03:33
Java函数重载相对于函数多态的优势和劣势 2024-09-23 11:03:02
“科大讯飞智能办公本Air2pro”产品特色及配置参数 2024-09-23 10:54:01
C++ 函数重载对编译器优化有何影响? 2024-09-23 10:45:02
电脑消息提醒怎么关 win11系统关闭消息通知的方法教程 2024-09-23 10:42:40
Meme、Ton 小游戏吞噬市场,一场不止于 CEX 的“行业出清”? 2024-09-23 10:30:50
AAVE链上数据深度分析报告 2024-09-23 10:30:33
**问题 为啥开头不写结束符号 ?> 就写一个 就写一个P粉052048067来自于2024-09-11 18:01:19
0
1
383 按照老师的方法不传值给TP6后台,再接收参数。出现以下错误。怎么办 http://localhost/index.php/admin/index/userliste 的远程资源。(原因:CORS 头缺少 'Access-Control-Al... 凡人来自于2024-07-09 15:20:49
1
39
1841 请问写php项目都要用到git吗 请问写php项目都要用到git吗 PHP中文网用户-4202961来自于2024-06-11 14:28:59
0
57
2458 请问能提供下源码么 请问能提供下源码么?想对照着看 周珂儿来自于2024-06-06 08:56:32
0
47
2188 为什么我用的laravel10不走handle文件中的render方法,无法输出断点内容 为什么我用的laravel10不走handle文件中的render方法,无法输出断点内容 许飞来自于2024-06-02 14:41:32
0
50
1705 小鱼AI助手免费使用!http://ai.52xuejs.cn/#/chat 小鱼AI助手免费使用!http://ai.52xuejs.cn/#/chat 会飞的汤姆来自于2024-05-28 03:09:58
0
47
2262 function_exists()无法判定自定义函数 function test() { return true; } ... 凡人来自于2024-04-29 11:01:01
0
64
3148 google 浏览器 手机版显示的怎么实现 老师您好,google 浏览器怎么变成手机版样式的? 艾尼宛尔.亚森来自于2024-04-23 00:22:19
0
51
2960 子窗口操作父窗口,输出没反应 前两句可执行,最后一句没法应 P粉722478067来自于2024-04-19 15:37:47
0
49
2695 父窗口没有输出 document.onclick = function(){ window.opener.document.write('我是子窗口的输出'); &nb... P粉722478067来自于2024-04-18 23:52:34
0
47
2517 相关专题 更多>
摄像头安装教程
摄像头品牌介绍
大华摄像头安装教程
海康威视摄像头安装教程
小米摄像头安装教程
丢包率多少是正常范围
未来计算机的发展趋势是什么
打电话总说在通话中的原因