Home > CMS Tutorial > WordPress > A friendly introduction to high-level components in React

A friendly introduction to high-level components in React

WBOY
Release: 2023-09-04 14:01:09
Original
709 people have browsed it

Higher-Order Components (HOC) are an interesting technique in React for refactoring similar components that share almost the same logic. I know this sounds abstract and advanced. However, it is an architectural pattern that is not specific to React, so you can do a lot with this approach.

For example, you can use it to add a loading indicator to a component without adjusting the original component, or you can hide a component's properties to make it less verbose. There are many applications and I tried to cover most of them in this tutorial.

There are several other tutorials that can teach you about HOCs, but most of them are aimed at advanced React developers. When I started learning React, I struggled to understand the concept of higher order components and how to incorporate HOCs into my projects to write better code. This article explains everything you need to know about HOCs from inception to incubation.

Overview

This tutorial is divided into three parts. The first part will introduce the concept of higher-order components. Here we will discuss the syntax you need to know before looking at higher order functions and HOCs. Part Two is the most exciting part of the series, where you'll see practical examples of HOCs. We will use HOC to create forms, authorizations and many other things.

In the third part of this tutorial, we will focus more on best practices and things to consider when implementing higher-order components. We'll also briefly cover alternative patterns for code sharing in React, such as Render props.

Before starting, it’s best to take a look at the tutorials on stateful components and stateless components to better understand React’s component architecture.

ES6 Syntax Cheat Sheet

We'll get started soon. But before that, there are a few things I think you should know. I prefer to use ES6 syntax whenever possible, it works well with HOCs. As a beginner, HOC makes sense, but some of the ES6 syntax doesn't. Therefore, I recommend that you skim this section first so that you can come back to it later.

Arrow function

Arrow functions are regular function expressions, but with shorter syntax. They are best suited for non-method functions, which is what we are particularly interested in. Here are some examples to get you started:

Function without parameters

/* 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"
Copy after login

Function with a single parameter

/* 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 }
}

Copy after login

Function with multiple parameters

/* 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]
    })
Copy after login

Currying in Functional Programming

While the name implies that it is related to an exotic dish in popular Indian cuisine, this is not the case. Currying helps you decompose a function that accepts multiple arguments into a series of functions that accept one argument at a time. Here is an example:

//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
Copy after login

The function accepts only one parameter and returns a function that accepts another parameter, and this continues until all parameters are satisfied.

curriedSum
// (a) => (b) => a+b

curriedSum(4)

// (b) => 4+b

curriedSum(4)(5)

//4+5
Copy after login

A closely related term is called "partial application". Some applications create new functions by pre-populating some parameters of an existing function. The arity of the newly created function (i.e. the number of arguments) will be less than the arity of the original function.

Propagation syntax

The expansion operator expands the contents of an array, string, or object expression. The following is a list of operations you can perform using the spread operator

Extended syntax in function calls

/*Spread Syntax in Function Calls */
const add = (x,y,z) => x+y+z

const args = [1,2,3]

add(...args) 
// 6

Copy after login

Extended syntax in array literals

/* Spread in Array Literals */

const twoAndThree = ['two', 'three']; 
const numbers = ['one', ...twoAndThree, 'four', 'five']; 
// ["one", "two", "three", "four", "five"]

Copy after login

Extended syntax in object literals

/* 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"
  }
  
*/
        
Copy after login

I personally like the way three dots make it easier for you to pass existing props to child components or create new ones.

Expand operator in React

const ParentComponent = (props) => {
  const newProps = { foo: 'default' };
  
  return (
      <ChildComponent 
  		{...props} {...newProps} 
  	/>
  )
}
Copy after login

Now that we understand the basic ES6 syntax for building HOCs, let’s see what they are.

Higher-order functions

What is a higher-order function? Wikipedia has a simple definition:

In mathematics and computer science, a higher-order function (also called a functional, functional form, or functor) is a function that accepts one or more functions as arguments or returns a function as its result, or both. function of it.

You've probably used higher-order functions in JavaScript in some form before, because that's how JavaScript works. Functions that pass anonymous functions or callbacks as arguments or return another function - all of these are higher-order functions. The code below creates an essentially higher order calculator function.

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);
 
  }
Copy after login

Let’s take a deeper look at this. calculator() Accepts a function as input and returns another function - this is exactly our definition of a higher-order function. Because we used rest parameters syntax, the returned function collects all of its parameters in an array.

Then, the input function is called with all arguments passed and the output is logged to the console. So calculator is a curried higher-order function, and you can use calculator like this:

calculator(multiply)(2,4);
// returns 8

calculator(add)(3,6,9,12,15,18); 
// returns 63
Copy after login

插入一个函数,例如 add()multiply() 和任意数量的参数,以及 calculator()将从那里拿走它。所以计算器是一个扩展了 add()multiply() 功能的容器。它使我们能够在更高或更抽象的层面上处理问题。乍一看,这种方法的好处包括:

  1. 代码可以在多个函数中重复使用。
  2. 您可以在容器级别添加所有算术运算通用的额外功能。
  3. 更具可读性,并且能更好地表达程序员的意图。

现在我们对高阶函数有了一个很好的了解,让我们看看高阶组件的能力。

高阶组件

高阶组件是一个接受组件作为参数并返回该组件的扩展版本的函数。

(InputComponent) => {
    return ExtendedComponent 
    }
    
// or alternatively

InputComponent => ExtendedComponent

Copy after login

扩展组件 组成 InputComponentExtendedComponent 就像一个容器。它呈现 InputComponent,但因为我们返回一个新组件,所以它添加了一个额外的抽象层。您可以使用此层添加状态、行为甚至样式。如果您愿意,您甚至可以决定根本不渲染 InputComponent — HOC 能够做到这一点以及更多。

下面的图片应该可以消除混乱(如果有的话)。

React 中高阶组件的友好介绍

理论已经讲完了,让我们开始看代码。下面是一个非常简单的 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 />
    }
}
Copy after login

withGreyBg 函数将一个组件作为输入并返回一个新组件。我们不是直接组合 Card 组件并将样式标签附加到每个单独的组件,而是创建一个 HOC 来实现此目的。高阶组件包装原始组件并在其周围添加 <div> 标签。需要注意的是,这里你必须手动将 props 分两层传递下去。我们没有做任何花哨的事情,但这就是正常的 HOC 的样子。下图更详细地演示了 withGreyBg() 示例。

React 中高阶组件的友好介绍

虽然这目前看起来不是特别有用,但好处并不小。考虑这种情况。您正在使用 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']
        },
Copy after login

摘要

在本教程中,我们学习了 HOC 的基本概念。 HOC 是构建可重用组件的流行技术。我们首先讨论基本的 ES6 语法,以便您更容易习惯箭头函数并编写现代 JavaScript 代码。

然后我们了解了高阶函数及其工作原理。最后,我们接触了高阶组件并从头开始创建了 HOC。

接下来,我们将通过实际示例介绍不同的 HOC 技术。在那之前请继续关注。在评论部分分享你的想法。

The above is the detailed content of A friendly introduction to high-level components in React. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template