[ffxixslh] React - 学习笔记 - HOC

本文介绍了React中的高阶组件(HOC)概念,通过实例展示了如何创建和使用高阶组件来实现组件的复用和增强。具体应用包括初始化props、渲染判断鉴权和劫持生命周期。在增强props的场景中,高阶组件用于注入额外的上下文数据;在登录鉴权场景中,高阶组件用于控制组件是否需要登录才能显示;在测试组件渲染时长的场景中,高阶组件帮助计算组件的渲染时间。
摘要由CSDN通过智能技术生成

高阶组件

高阶组件是参数为组件,返回值是新组件的函数

如果存在某些组件的实现流程是相同的,可以将它们的共有流程抽离成一个抽象组件,编写其高阶组件

// HOC.jsx
import React, { PureComponent } from "react";

export class CC extends PureComponent {
  render() {
    return <div>CC</div>;
  }
}

export const FC = () => {
  return <div>FC</div>;
};

function EnhancedClassComponent(WrappedComponent) {
  return class NewClassComponent extends PureComponent {
    render() {
      return <WrappedComponent {...this.props} />;
    }
  };
}

function EnhancedFunctionComponent(WrappedComponent) {
  return function NewFunctionComponent(props) {
    return <WrappedComponent {...props} />;
  };
}

const CWithEnhance = EnhancedClassComponent(CC);
const FWithEnhance = EnhancedFunctionComponent(FC);

export default function HOC() {
  return (
    <>
      <CWithEnhance name="CC" />
      <FWithEnhance name="FC" />
    </>
  );
}

例子实现了一个包装函数:

在这里插入图片描述

应用场景

应用1:增强props

类似于偏函数的思想,可以先对组件初始化一些数据,再返回新的 “增强型” 的组件:

- import React, { PureComponent } from "react";
+ import React, { PureComponent, createContext } from "react";

+ const UserContext = createContext({
+   language: "chinese",
+   region: "China",
+ });

export const FC = ({ name, language, region }) => {
+   return <div>{`name:${name} language:${language} region:${region}`}</div>;
};

export class CC extends PureComponent {
  render() {
    return (
+       <div>{`name:${this.props.name} language:${this.props.language} region:${this.props.region}`}</div>
    );
  }
}

function EnhancedClassComponent(WrappedComponent) {
  return class NewClassComponent extends PureComponent {
    render() {
      return (
+         <UserContext.Consumer>
+           {(user) => {
-             return <WrappedComponent {...this.props} />;
+             return <WrappedComponent {...this.props} {...user} />;
+           }}
+         </UserContext.Consumer>
      );
    }
  };
}

function EnhancedFunctionComponent(WrappedComponent) {
  return function NewFunctionComponent(props) {
    return (
+       <UserContext.Consumer>
+         {(user) => {
-           return <WrappedComponent {...props} />;
+           return <WrappedComponent {...props} {...user} />;
+         }}
+       </UserContext.Consumer>
    );
  };
}

const CWithEnhance = EnhancedClassComponent(CC);
const AWithEnhance = EnhancedFunctionComponent(FC);

export default function HOC() {
  return (
+     <UserContext.Provider value={{ language: "zh-CN", region: "CN" }}>
        <CWithEnhance name="CC" />
        <AWithEnhance name="FC" />
+     </UserContext.Provider>
  );
}
应用2:渲染判断鉴权
场景1:登录鉴权

如果出现需要判断登录的场景,这时用高阶组件可以在渲染前做出逻辑判断,返回渲染结果:

import React from "react";

const LoginPage = () => {
  return <h2>Login</h2>;
};

const CartPage = () => {
  return <h2>Cart</h2>;
};

const withAuth = (WrappedComponent) => {
  const NewCpn = (props) => {
    if (props.isLogin) return <WrappedComponent {...props} />;
    return <LoginPage {...props} />;
  };

  NewCpn.displayName = "AuthCpn";
  return NewCpn;
};

const AuthCartPage = withAuth(CartPage);

export default function Auth() {
  return (
    <>
      <AuthCartPage isLogin={false} />
    </>
  );
}

在这里插入图片描述

在这里插入图片描述

场景2:劫持生命周期

如果需要测试组件渲染时长,一般做法是在类的生命周期函数 componentWillMountcomponentDidMount 中使用 Date.now() 函数获取时间戳再求差值;高级做法是使用高阶组件生成一个包装函数,将组件放入其中再按照传统方法求值:

import React, { Component } from "react";

const LoginPage = () => {
  return <h2>Login</h2>;
};

const withRenderTime = (WrappedComponent) => {
  return class extends Component {
    UNSAFE_componentWillMount() {
      this.startTime = Date.now();
    }

    componentDidMount() {
      this.endTime = Date.now();
      const delta = this.endTime - this.startTime;
      console.log(delta);
    }

    render() {
      return <WrappedComponent {...this.props} />;
    }
  };
};

const LoginTime = withRenderTime(LoginPage);

export default function Time() {
  return (
    <>
      <LoginTime />
    </>
  );
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值