React中的高阶组件(HOC)

143 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第3天,点击查看活动详情

高阶函数:1.函数的参数是函数,2.函数的返回值是一个函数,满足一点该函数就是高阶函数。在js中例如:map,filter,reduce方法都是高阶函数

高阶组件的定义:

高阶组件是React中复用组件逻辑的一种高级技巧,HOC(Higher Order Component,
简称:HOC),是一种基于React组合特征形成的设计模式(装饰器模式)与类中的装饰器相似,目的都是增强组件的功能。

高阶组件本质:

高阶组件只是一个包装另外一个React组件的组件
+实现形式是一个函数,函数参数是一个组件,返回值仍是一个新组件

高阶函数的优点

1.对原有组件增强和优化
2.可以对原有组件的state,props和逻辑执行增删改操作,一般用于代码重用和组件增强优化

高阶组件的缺点

在dom树中会增加多余的节点

image.png

高阶组件应用场景

  • 1.条件渲染鉴权(例如判断登录和注册页面)
  • 2.提取组件的公共逻辑,利用高阶组件的形式,整合到每一个组件中,代码复用

高阶组件的功能

  • 1.增强props
  • 2.状态抽离
  • 3.渲染劫持

增强props

import React from "react";

function enhanceProps(Component) {
  return (props) => {
    return <Component {...props} region="台湾省"></Component>;
  };
}

function City(props) {
  return (
    <div>
      <h2>
        Name: {props.name}, 等级: {props.level} 区域:{props.region}
      </h2>
    </div>
  );
}

const EnhanceCity = enhanceProps(City);

function Country(props) {
  return (
    <div>
      <h2>
        Name: {props.name}, 等级: {props.level} 区域:{props.region}
      </h2>
    </div>
  );
}
const EnhanceCountry = enhanceProps(Country);

function CithComponent() {
  return (
    <div>
      hoc
      <EnhanceCity name="jack" level={1}></EnhanceCity>
      <EnhanceCountry name="tom" level={2}></EnhanceCountry>
    </div>
  );
}

export default CithComponent;

状态抽离

import React, { useState } from "react";

// 高阶组件抽离state
// 1.将input抽离出来,变成一个单独的组件
const NameInput = (props) => {
  return (
    <input type="text" value={props.value} onChange={props.handleChange}></input>
  );
};

// 2.在高阶组件中返回一个新的组件,我们在这个组件中定义属性和方法
function withChange(Component) {
  return () => {
    const [value, setValue] = useState("");
    const handleChange = (e) => {
      setValue(e.target.value);
    };
    return <Component value={value} handleChange={handleChange}></Component>;
  };
}
// 3.返回一个新组件
const WrappedNameInput = withChange(NameInput);

// 4.这个时候WithComponent就是一个无状态组件,他的组件都被抽离了
function WithComponent() {
  return (
    <div>
      <h2>状态抽离</h2>
      <WrappedNameInput></WrappedNameInput> <br/>
      <WrappedNameInput></WrappedNameInput> <br/>
      <WrappedNameInput></WrappedNameInput>
    </div>
  );
}

export default WithComponent;

条件渲染

function UserPage() {
  return <h2>用户页面</h2>;
}

function AdminPage() {
  return <h2>管理员页面</h2>;
}

function withAuth(Component) {
  const newComponent = function (props) {
    console.log('props',props);
    const { isAdmin } = props;
    if (isAdmin) {
      return <AdminPage {...props}> </AdminPage>;
    } else {
      return <Component {...props}> </Component>;
    }
  };
  newComponent.displayName = 'VPN'
  return newComponent;
}

const AuthComponent = withAuth(UserPage);

function ChangeComponent() {
  return (
    <div>
      高阶组件实现登录鉴权
      <AuthComponent isAdmin={true}> </AuthComponent>
      {/* <AuthComponent isAdmin={false}> </AuthComponent> */}
    </div>
  );
}

export default ChangeComponent;

自定义hook是实现某个功能的代码片段。

装饰器和高阶组件用于增强类,类方法或增强组件的功能。

个人觉得,优点:自定义hook > 装饰器 > 高阶组件,函数式组件使用的组合的思想,而不是使用继承的思想.