Maison > Article > Tutoriel CMS > Une introduction conviviale aux composants de haut niveau de React
Les composants d'ordre supérieur (HOC) sont une technique intéressante dans React pour refactoriser des composants similaires qui partagent presque la même logique. Je sais que cela semble abstrait et avancé. Cependant, il s’agit d’un modèle architectural qui n’est pas spécifique à React, vous pouvez donc faire beaucoup de choses avec cette approche.
Par exemple, vous pouvez l'utiliser pour ajouter un indicateur de chargement à un composant sans ajuster le composant d'origine, ou vous pouvez masquer les propriétés d'un composant pour le rendre moins verbeux. Il existe de nombreuses applications et j'ai essayé d'en couvrir la plupart dans ce tutoriel.
Il existe plusieurs autres tutoriels qui peuvent vous renseigner sur les HOC, mais la plupart d'entre eux sont destinés aux développeurs React avancés. Lorsque j'ai commencé à apprendre React, j'ai eu du mal à comprendre le concept de composants d'ordre supérieur et comment intégrer des HOC dans mes projets pour écrire un meilleur code. Cet article explique tout ce que vous devez savoir sur les HOC, de la création à l'incubation.
Ce tutoriel est divisé en trois parties. La première partie introduira le concept de composants d’ordre supérieur. Ici, nous discuterons de la syntaxe que vous devez connaître avant d'examiner les fonctions d'ordre supérieur et les HOC. La deuxième partie est la partie la plus passionnante de la série, où vous verrez des exemples pratiques de HOC. Nous utiliserons HOC pour créer des formulaires, des autorisations et bien d'autres choses.
Dans la troisième partie de ce didacticiel, nous nous concentrerons davantage sur les meilleures pratiques et les éléments à prendre en compte lors de l'implémentation de composants d'ordre supérieur. Nous aborderons également brièvement les modèles alternatifs de partage de code dans React, tels que les accessoires de rendu.
Avant de commencer, il est préférable de jeter un œil aux tutoriels sur les composants avec état et les composants sans état pour mieux comprendre l'architecture des composants de React.
Nous allons bientôt commencer. Mais avant cela, il y a quelques choses que vous devriez savoir. Je préfère utiliser la syntaxe ES6 autant que possible, elle fonctionne bien avec les HOC. En tant que débutant, HOC a du sens, mais certaines syntaxes ES6 ne le sont pas. Par conséquent, je vous recommande de parcourir d’abord cette section afin de pouvoir y revenir plus tard.
Les fonctions fléchées sont des expressions de fonctions régulières, mais avec une syntaxe plus courte. Ils sont mieux adaptés aux fonctions non-méthodes, ce qui nous intéresse particulièrement. Voici quelques exemples pour vous aider à démarrer :
/* 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] })
Bien que son nom implique qu'il est lié à un plat exotique de la cuisine indienne populaire, ce n'est pas le cas. Le currying vous aide à décomposer une fonction qui accepte plusieurs arguments en une série de fonctions qui acceptent un argument à la fois. Voici un exemple :
//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
La fonction ne prend qu'un seul paramètre et renvoie une fonction qui prend un autre paramètre, et cela continue jusqu'à ce que tous les paramètres soient remplis.
curriedSum // (a) => (b) => a+b curriedSum(4) // (b) => 4+b curriedSum(4)(5) //4+5
Un terme étroitement lié est appelé « application partielle ». Certaines applications créent de nouvelles fonctions en préremplissant certains paramètres d'une fonction existante. L'arité de la fonction nouvellement créée (c'est-à-dire le nombre d'arguments) sera inférieure à l'arité de la fonction d'origine.
L'opérateur spread développe le contenu d'un tableau, d'une chaîne ou d'une expression d'objet. Vous trouverez ci-dessous une liste des opérations que vous pouvez effectuer à l'aide de l'opérateur spread
/*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" } */
Personnellement, j'aime la façon dont trois points vous permettent de transmettre plus facilement des accessoires existants aux composants enfants ou d'en créer de nouveaux.
const ParentComponent = (props) => { const newProps = { foo: 'default' }; return ( <ChildComponent {...props} {...newProps} /> ) }
Maintenant que nous comprenons la syntaxe de base ES6 pour créer des HOC, voyons de quoi il s'agit.
Que sont les fonctions d’ordre supérieur ? Wikipédia a une définition simple :
En mathématiques et en informatique, une fonction d'ordre supérieur (également appelée forme fonctionnelle, fonctionnelle ou foncteur) est une fonction qui accepte une ou plusieurs fonctions comme arguments ou renvoie une fonction comme résultat, ou les deux fonctions.
Vous avez probablement déjà utilisé des fonctions d'ordre supérieur en JavaScript sous une forme ou une autre, car c'est ainsi que fonctionne JavaScript. Une fonction qui transmet une fonction anonyme ou un rappel en tant que paramètre ou renvoie une autre fonction - toutes ces fonctions sont des fonctions d'ordre supérieur. Le code ci-dessous crée une fonction de calcul d’ordre essentiellement supérieur.
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); }
Examinons cela de plus près. calculator()
Prend une fonction en entrée et renvoie une autre fonction - cela correspond parfaitement à notre définition d'une fonction d'ordre supérieur. Parce que nous avons utilisé la syntaxe des paramètres rest, la fonction renvoyée collecte tous ses paramètres dans un tableau.
Ensuite, la fonction d'entrée est appelée avec tous les arguments passés et la sortie est enregistrée sur la console. La calculatrice est donc une fonction d'ordre supérieur au curry, vous pouvez utiliser la calculatrice comme ceci :
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 示例,它将输入组件包装在 <div> 标记周围。从这里开始,我将把 <code class="inline">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 ( <div className="wrapper" style={bgStyle}> <WrappedComponent {...this.props} /> </div> ); } }; const SmallCardWithGreyBg = withGreyBg(SmallCard); const BigCardWithGreyBg = withGreyBg(BigCard); const HugeCardWithGreyBg = withGreyBg(HugeCard); class CardsDemo extends Component { render() { <SmallCardWithGreyBg {...this.props} /> <BigCardWithGreyBg {...this.props} /> <HugeCardWithGreyBg {...this.props /> } }
withGreyBg
函数将一个组件作为输入并返回一个新组件。我们不是直接组合 Card 组件并将样式标签附加到每个单独的组件,而是创建一个 HOC 来实现此目的。高阶组件包装原始组件并在其周围添加 <div> 标签。需要注意的是,这里你必须手动将 props 分两层传递下去。我们没有做任何花哨的事情,但这就是正常的 HOC 的样子。下图更详细地演示了 <code class="inline">withGreyBg()
示例。
虽然这目前看起来不是特别有用,但好处并不小。考虑这种情况。您正在使用 React 路由器,并且需要保护某些路由 - 如果用户未经过身份验证,则对这些路由的所有请求都应重定向到 /login
。我们可以使用 HOC 来有效管理受保护的路由,而不是重复身份验证代码。好奇想知道怎么做吗?我们将在下一个教程中介绍这一点以及更多内容。
注意:ECMAScript 中提出了一个称为装饰器的功能,可以轻松使用 HOC。但是,它仍然是一个实验性功能,因此我决定不在本教程中使用它。如果您使用的是 create-react-app,则需要先弹出才能使用装饰器。如果您运行的是最新版本的 Babel (Babel 7),您所需要做的就是安装 <em>babel-preset-stage-0</em>
然后将其添加到 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 技术。在那之前请继续关注。在评论部分分享你的想法。
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!