React js教程(18):React 中的高阶组件

作者 : 慕源网 本文共3824个字,预计阅读时间需要10分钟 发布时间: 2021-10-27 共291人阅读

本文是React 教程系列的一部分。您可以在此处找到本系列之前所有帖子的链接

介绍

在上一篇文章中,我们了解了 Portals 和 Error Boundary 以及它们在 ReactJS 中的用法。在本文中,我们将了解高阶组件 (HOC) 及其在 React 中的用法。

什么是 HOC?

HOC 不是 React 或任何其他编程语言的功能。它只是一个涉及 React 组合性质的概念。高阶组件也不是 React API 的一部分。一个组件将 Props 转换为 UI,而另一方面,高阶组件将一个组件转换为另一个组件

高阶组件的概念主要用于可重用性以及将组件分解为可以重用的简单且较小的功能。这使得一个函数能够执行单个任务,从而使整个应用程序易于调试和维护。

在 Haskell 语言中,受启发的伪代码具有以下签名。

hocFactory:: W: React.Component => E: React.Component   

其中 W 代表 WrappedComponent,它是一个被包装的 React 组件,E 代表增强组件,它返回一个新组件。

基本上,HOC 涉及操作 WrappedComponents,这可以通过两种方式完成。

  1. 属性代理(Props Proxy)
  2. 反向继承(Inheritance Inversion)

Props Proxy

在 Props Proxy 中,顾名思义,它传递从高阶组件接收的属性。

语法

function ppHOC(WrappedComponent) {  
   returnclass PP extends React.Component {  
      render() {  
         return <WrappedComponent {...this.props}/>  
      }  
   }  
}  

按照上面的语法,Props 代理返回 WrappedComponent 类型的 React 元素。

有很多方法可以表示 Props 代理。

  1. 操纵道具
  2. 抽象状态
  3. 通过 Refs 访问实例
  4. 用其他元素包裹 WrappedComponent

反向集成

这与 Props Proxy 完全不同。它允许 HOC 使用此关键字访问 WrappedComponents 实例。这让我们可以访问 props、state 和 render 方法。

语法

function iiHOC(WrappedComponent) {  
   return class Enhancer extends WrappedComponent {  
      render() {  
         return super.render()  
         }  
      }  
}  

所以,我们可以看到它逆转了Props Proxy的效果;因此,该名称暗示了继承反转,因为它扩展了 WrappedComponent。反转继承可用于 –

  1. 条件渲染
  2. 状态操纵

React 中高阶组件的演示

让我们创建一个小演示,以在表格中显示公司和员工的列表。在这个演示中,我们将创建一个组件作为 TableRowComponent 用于 CompanyComponent 和 EmployeeComponent 来仅将数据传递给 TableRowComponent。

对于上述实现,您需要首先创建 TableRowComponent.js 文件,在该文件中,根据输入创建一个完整的行。

import React, { Component } from 'react'    
    
class TableRowComponent extends Component {    
    render() {    
        return (    
            <tr>    
                <td>    
                    {this.props.obj.Id}    
                </td>    
                <td>    
                    {this.props.obj.Name}    
                </td>    
                <td>    
                    {this.props.obj.ContactNumber}    
                </td>    
            </tr>    
        )    
    }    
}    
    
export default TableRowComponent   
现在,我们将创建使用上述 TableRowComponent 的 EmployeeList.Js 文件。
import React, { Component } from 'react'    
import TableRowComponent from './TableRowComponent'    
    
export class EmployeeList extends Component {    
    constructor(props) {    
        super(props)    
        
        this.state = {    
             Employees:[    
                 {    
                     Id : 1,    
                     Name : 'ABC',    
                     ContactNumber: '1123456789'    
                 },    
                 {    
                    Id : 2,    
                    Name : 'XYZ',    
                    ContactNumber: '09873643775'    
                },    
                {    
                    Id : 3,    
                    Name : 'MNO',    
                    ContactNumber: '29354546675'    
                }    
             ]    
        }    
    }    
        
    tableRow(){    
        if(this.state.Employees instanceof Array){    
            return this.state.Employees.map(function(object,i){    
                return <TableRowComponent obj={object} key={i}></TableRowComponent>    
            })    
        }    
    }    
    render() {    
        return (    
            <div className="container">    
                <table>    
                    <thead>    
                        <tr>    
                            <td>Employee Id</td>    
                            <td>Employee Name</td>    
                            <td>Contact Number</td>    
                        </tr>    
                    </thead>    
                    <tbody>    
                        {this.tableRow()}    
                    </tbody>    
                </table>    
            </div>    
        )    
    }    
}    
    
export default EmployeeList 
现在,还要创建一个 CompanyList.js 文件。
import React, { Component } from 'react'    
import TableRowComponent from './TableRowComponent'    
    
export class CompanyList extends Component {    
    constructor(props) {    
        super(props)    
        
        this.state = {    
             Companies:[    
                 {    
                     Id :1,    
                     Name : 'Wipro',    
                     ContactNumber:'3567575'    
                 },    
                 {    
                    Id :2,    
                    Name : 'Google',    
                    ContactNumber:'3983945'    
                },    
                {    
                    Id :3,    
                    Name : 'Facebook',    
                    ContactNumber:'475686787'    
                }    
             ]    
        }    
    }    
        
    tableRow(){    
        if(this.state.Companies instanceof Array){    
            return this.state.Companies.map(function(object,i){    
                return <TableRowComponent obj={object} key={i}></TableRowComponent>    
            })    
        }    
    }    
    
    render() {    
        return (    
            <div className="container">    
            <table>    
                <thead>    
                    <tr>    
                        <td>Company Id</td>    
                        <td>Company Name</td>    
                        <td>Contact Number</td>    
                    </tr>    
                </thead>    
                <tbody>    
                    {this.tableRow()}    
                </tbody>    
            </table>    
        </div>    
        )    
    }    
}    
    
export default CompanyList    
现在,在 App.js 文件中添加新添加的 CompanyList 和 EmployeeList。
import React from 'react';      
import './App.css';    
import './css/custom.css';    
import ErrorBoundary from './components/ErrorBoundary'    
import CompanyList from './components/CompanyList'    
import EmployeeList from './components/EmployeeList';    
    
function App() {    
  return (        
    <div>    
      <h1>Company List</h1>    
      <CompanyList></CompanyList>    
      <h1> Employee List</h1>    
      <EmployeeList></EmployeeList>        
    </div>    
  );    
}    
    
export default App;  

上述程序的输出将显示如下。

React js教程(18):React 中的高阶组件

在上面的例子中,我们回顾了高阶组件的工作原理。

对于高阶组件,我们需要记住下面提到的两件事。

  • 这些组件将输入作为组件并
  • 返回一个新组件。

高阶组件通常用于第三方库,如 Redux 或 React Router。

简而言之,HOC 可以帮助您以更好的方式组织 React 代码并减少代码冗余。甚至像 Redux 或 React Router 这样的第三方库也使用这个概念。

高阶组件的优势

  1. 当需要捆绑重复模式时使用。
  2. 让调试更简单
  3. 通过与 HOC 无关的 props。

高阶组件的缺点

  1. 不需要过度使用,也可以使用其他方法
  2. 它改变原始组件。
  3. 永远不要在 render() 方法中使用高阶组件。

高阶组件的用例

  1. Loader 创建一个高阶组件,可以在需要时使用。
  2. 每当需要管理常见的用户交互时。
  3. 当用户需要定义一些特定的样式时。
  4. 您可以将 Dialog 创建为一个组件,并可以在整个应用程序中使用。

概括

在本文中,我们了解了高阶组件的概念和用法。在下一篇文章中,我们将详细介绍 React.js 中 Render Props 和 Context 的概念。

Next >>在 React.js 渲染属性(Render Props)和上下文(Content)


慕源网 » React js教程(18):React 中的高阶组件

常见问题FAQ

程序仅供学习研究,请勿用于非法用途,不得违反国家法律,否则后果自负,一切法律责任与本站无关。
请仔细阅读以上条款再购买,拍下即代表同意条款并遵守约定,谢谢大家支持理解!

发表评论

开通VIP 享更多特权,建议使用QQ登录