Higher Order Components (HOC) ist eine interessante Technik in React zum Refactoring ähnlicher Komponenten, die fast die gleiche Logik haben. Ich weiß, das klingt abstrakt und fortgeschritten. Allerdings handelt es sich um ein Architekturmuster, das nicht spezifisch für React ist, sodass Sie mit diesem Ansatz viel erreichen können.
Sie können damit beispielsweise einer Komponente einen Ladeindikator hinzufügen, ohne die ursprüngliche Komponente anzupassen, oder Sie können die Eigenschaften einer Komponente ausblenden, um sie weniger ausführlich zu gestalten. Es gibt viele Anwendungen und ich habe versucht, die meisten davon in diesem Tutorial abzudecken.
Es gibt mehrere andere Tutorials, die Ihnen etwas über HOCs beibringen können, aber die meisten davon richten sich an fortgeschrittene React-Entwickler. Als ich anfing, React zu lernen, hatte ich Schwierigkeiten, das Konzept von Komponenten höherer Ordnung zu verstehen und zu verstehen, wie ich HOCs in meine Projekte integrieren kann, um besseren Code zu schreiben. In diesem Artikel erfahren Sie alles, was Sie über HOCs von der Gründung bis zur Inkubation wissen müssen.
Dieses Tutorial ist in drei Teile unterteilt. Im ersten Teil wird das Konzept der Komponenten höherer Ordnung vorgestellt. Hier besprechen wir die Syntax, die Sie kennen müssen, bevor Sie sich Funktionen und HOCs höherer Ordnung ansehen. Teil zwei ist der aufregendste Teil der Serie, in dem Sie praktische Beispiele für HOCs sehen. Wir werden HOC verwenden, um Formulare, Berechtigungen und viele andere Dinge zu erstellen.
Im dritten Teil dieses Tutorials konzentrieren wir uns mehr auf Best Practices und Dinge, die bei der Implementierung von Komponenten höherer Ordnung zu beachten sind. Wir werden auch kurz auf alternative Muster für die Codefreigabe in React eingehen, z. B. Render-Requisiten.
Bevor Sie beginnen, schauen Sie sich am besten die Tutorials zu Stateful Components und Stateless Components an, um die Komponentenarchitektur von React besser zu verstehen.
Wir werden bald loslegen. Aber vorher gibt es meiner Meinung nach ein paar Dinge, die Sie wissen sollten. Ich bevorzuge wann immer möglich die ES6-Syntax, sie funktioniert gut mit HOCs. Als Anfänger macht HOC Sinn, einige der ES6-Syntax jedoch nicht. Daher empfehle ich Ihnen, diesen Abschnitt zunächst zu überfliegen, damit Sie später darauf zurückkommen können.
Pfeilfunktionen sind reguläre Funktionsausdrücke, jedoch mit kürzerer Syntax. Sie eignen sich am besten für Nicht-Methoden-Funktionen, was uns besonders interessiert. Hier sind einige Beispiele, um Ihnen den Einstieg zu erleichtern:
/* 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] })
Obwohl der Name vermuten lässt, dass es sich um ein exotisches Gericht der beliebten indischen Küche handelt, ist dies nicht der Fall. Mit Currying können Sie eine Funktion, die mehrere Argumente akzeptiert, in eine Reihe von Funktionen zerlegen, die jeweils ein Argument akzeptieren. Hier ein Beispiel:
//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
Die Funktion akzeptiert nur einen Parameter und gibt eine Funktion zurück, die einen anderen Parameter akzeptiert. Dies wird so lange fortgesetzt, bis alle Parameter erfüllt sind.
curriedSum // (a) => (b) => a+b curriedSum(4) // (b) => 4+b curriedSum(4)(5) //4+5
Ein eng verwandter Begriff heißt „Teilanwendung“. Einige Anwendungen erstellen neue Funktionen, indem sie einige Parameter einer vorhandenen Funktion vorab ausfüllen. Die Arität (d. h. die Anzahl der Parameter) der neu erstellten Funktion wird kleiner sein als die Arität der ursprünglichen Funktion.
Der Spread-Operator erweitert den Inhalt eines Arrays, einer Zeichenfolge oder eines Objektausdrucks. Nachfolgend finden Sie eine Liste der Operationen, die Sie mit dem Spread-Operator
ausführen können/*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" } */
Mir persönlich gefällt die Art und Weise, wie drei Punkte es Ihnen erleichtern, vorhandene Requisiten an untergeordnete Komponenten zu übergeben oder neue zu erstellen.
const ParentComponent = (props) => { const newProps = { foo: 'default' }; return ( <ChildComponent {...props} {...newProps} /> ) }
Da wir nun die grundlegende ES6-Syntax zum Erstellen von HOCs verstehen, wollen wir uns ansehen, was sie sind.
Was sind Funktionen höherer Ordnung? Wikipedia hat eine einfache Definition:
In der Mathematik und Informatik ist eine Funktion höherer Ordnung (auch Funktion, Funktionsform oder Funktor genannt) eine Funktion, die eine oder mehrere Funktionen als Argumente akzeptiert oder eine Funktion als Ergebnis zurückgibt, oder beide Funktionen.
Sie haben wahrscheinlich schon einmal in irgendeiner Form Funktionen höherer Ordnung in JavaScript verwendet, denn genau so funktioniert JavaScript. Funktionen, die anonyme Funktionen oder Rückrufe als Argumente übergeben oder eine andere Funktion zurückgeben – all dies sind Funktionen höherer Ordnung. Der folgende Code erstellt eine Rechnerfunktion im Wesentlichen höherer Ordnung.
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); }
Lass uns einen genaueren Blick darauf werfen. calculator()
Nimmt eine Funktion als Eingabe und gibt eine andere Funktion zurück – das passt perfekt zu unserer Definition einer Funktion höherer Ordnung. Da wir die Restparameter-Syntax verwendet haben, sammelt die zurückgegebene Funktion alle ihre Parameter in einem Array.
Dann wird die Eingabefunktion mit allen übergebenen Argumenten aufgerufen und die Ausgabe wird in der Konsole protokolliert. Der Rechner ist also eine Curry-Funktion höherer Ordnung. Sie können den Rechner wie folgt verwenden:
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>
标记周围。从这里开始,我将把 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 的样子。下图更详细地演示了 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 技术。在那之前请继续关注。在评论部分分享你的想法。
Das obige ist der detaillierte Inhalt vonEine freundliche Einführung in High-Level-Komponenten in React. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!