React 中高階組件的友善介紹

WBOY
發布: 2023-09-04 14:01:09
原創
658 人瀏覽過

高階元件(HOC)是 React 中一項有趣的技術,用於重構共享幾乎相同邏輯的類似元件。我知道這聽起來很抽象而且很高級。然而,它是一種並非特定於 React 的架構模式,因此您可以使用該方法來做很多事情。

例如,您可以使用它向某個組件添加載入指示器,而無需調整原始組件,或者您可以隱藏組件的屬性以使其不那麼冗長。應用程式有很多,我試圖在本教程中介紹其中的大部分。

還有其他幾個教程可以教您有關 HOC 的知識,但其中大多數都是針對高級 React 開發人員的。當我開始學習 React 時,我很難理解高階元件的概念以及如何將 HOC 合併到我的專案中以編寫更好的程式碼。本文將解釋您需要了解的 HOC 從頭到孵化的所有內容。

概述

本教程分為三個部分。第一部分將介紹高階組件的概念。在這裡,我們將討論在查看高階函數和 HOC 之前需要了解的語法。第二部分是本系列中最令人興奮的部分,您將看到 HOC 的實際範例。我們將使用 HOC 來建立表單、授權和許多其他事情。

在本教程的第三部分中,我們將更專注於最佳實踐以及實現高階元件時需要考慮的事項。我們也將簡要介紹 React 中程式碼共享的替代模式,例如 Render props。

在開始之前,最好先看看有狀態元件與無狀態元件的教學課程,以便更能理解 React 的元件架構。

ES6 語法備忘單

我們很快就會動手。但在此之前,我認為您應該了解一些事情。我喜歡盡可能使用 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"
  }
  
*/
        
登入後複製

我個人喜歡三個點可以讓您更輕鬆地將現有道具傳遞給子組件或創建新道具的方式。

#React 中的擴充運算子

const ParentComponent = (props) => {
  const newProps = { foo: 'default' };
  
  return (
      <ChildComponent 
  		{...props} {...newProps} 
  	/>
  )
}
登入後複製

現在我們已經了解了建構 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() 功能的容器。它使我们能够在更高或更抽象的层面上处理问题。乍一看,这种方法的好处包括:

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

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

高阶组件

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

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

InputComponent => ExtendedComponent

登入後複製

扩展组件 组成 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 />
    }
}
登入後複製

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']
        },
登入後複製

摘要

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

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

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

以上是React 中高階組件的友善介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!