【前端知识】React 基础巩固(二十五)——高阶组件

React 基础巩固(二十五)------高阶组件

高阶函数

  • 定义:接收一个或多个函数作为输入输出一个函数 的函数
  • JS 中常用的mapfilterreduce都是高阶函数

高阶组件(Higher-Order Components, HOC)

  • 定义:高阶组件是参数为函数,返回值为新组件的函数
  • 高阶组件本质是函数
  • 高阶组件并不是 React API 的一部分,它是基于 React 的组合特性而形成的设计模式
javascript 复制代码
import React, { PureComponent } from "react";

// 定义一个高阶组件
function hoc(Cpn) {
  // 1.定义一个类组件
  class NewCpn1 extends PureComponent {
    render() {
      return <Cpn />;
    }
  }
  return NewCpn1;
  // 2.定义一个函数组件
  function NewCpn2(props) {}
  return NewCpn2;
}

class HelloWorld extends PureComponent {
  render() {
    return (
      <div>
        <h1>hello world</h1>
      </div>
    );
  }
}

const HelloWorldHOC = hoc(HelloWorld);

export class App extends PureComponent {
  render() {
    return (
      <div>
        <HelloWorld />
        <HelloWorldHOC />
      </div>
    );
  }
}

export default App;

高阶组件的应用场景(一)------ 用户信息增强

  • 构建用户信息增强高阶组件
javascript 复制代码
import React, { PureComponent } from "react";
// 定义组件: 给一些需要特殊数据的组件注入props
function enhanceUserInfo(OriginCmp) {
  class NewComponent extends PureComponent {
    constructor() {
      super();

      this.state = {
        userInfo: {
          name: "outman",
          level: 123,
        },
      };
    }

    render() {
      return <OriginCmp {...this.props} {...this.state.userInfo} />;
    }
  }

  return NewComponent;
}

export default enhanceUserInfo;
  • 使用高阶组件拦截组件并注入用户信息
javascript 复制代码
import React, { PureComponent } from "react";
import enhanceUserInfo from "./enhance_props";

const Home = enhanceUserInfo(function Home(props) {
  return (
    <h1>
      Home: {props.name} - {props.level} - {props.age}
    </h1>
  );
});

const Profile = enhanceUserInfo(function Profile(props) {
  return (
    <h1>
      Profile: {props.name} - {props.level}
    </h1>
  );
});

const Hello = enhanceUserInfo(function Hello(props) {
  return (
    <h1>
      Hello: {props.name} - {props.level}
    </h1>
  );
});

export class App extends PureComponent {
  render() {
    return (
      <div>
        <Home age={"888"} />
        <Profile />
        <Hello />
      </div>
    );
  }
}

export default App;

高阶组件的应用场景(二)------ 拦截并处理Context传参

  • 构建 ThemeContext
javascript 复制代码
import { createContext } from "react";

const ThemeContext = createContext();

export default ThemeContext;
  • 构建 App.jsx,通过 ThemeContext.Provider 传递参数给<Product/>
javascript 复制代码
import React, { PureComponent } from "react";
import ThemeContext from "./context/theme_context";
import Product from "./Product";

export class App extends PureComponent {
  render() {
    return (
      <div>
        <ThemeContext.Provider value={{ color: "red", size: 18 }}>
          <Product />
        </ThemeContext.Provider>
      </div>
    );
  }
}

export default App;
  • 构建 Product.jsx, 在 Product 中,通过 ThemeContext.Consumer 消费参数
javascript 复制代码
import React, { PureComponent } from "react";
import ThemeContext from "./context/theme_context";

// 直接使用上下文方式传递props参数
export class Product extends PureComponent {
  render() {
    return (
      <div>
        Product:
        <ThemeContext.Consumer>
          {(value) => {
            return (
              <h2>
                theme: {value.color} - {value.size}
              </h2>
            );
          }}
        </ThemeContext.Consumer>
      </div>
    );
  }
}

export default Product;
  • 若每次都要采用上述方式,通过ThemeContext.Consumer消费参数,太过繁琐。故,可以利用高阶组件进行处理。
  • 构建高阶组件 with_theme
javascript 复制代码
import ThemeContext from "./theme_context";

function withTheme(OriginComponent) {
  return (props) => {
    return (
      <ThemeContext.Consumer>
        {(value) => {
          return <OriginComponent {...value} {...props} />;
        }}
      </ThemeContext.Consumer>
    );
  };
}

export default withTheme;
  • 通过withTheme包装Product
javascript 复制代码
import React, { PureComponent } from "react";
import withTheme from "./context/with_theme";

// 利用高阶函数方式,更简洁
export class Product extends PureComponent {
  render() {
    const { color, size } = this.props;
    return (
      <div>
        Product:
        {color} - {size}
      </div>
    );
  }
}

export default withTheme(Product);

高阶组件的应用场景(三)------ 登陆鉴权

  • 构建登陆鉴权高阶组件
javascript 复制代码
function loginAuth(OriginComponent) {
  return (props) => {
    // 从localStorage 中获取 token
    const token = localStorage.getItem("token");

    if (token) {
      return <OriginComponent {...props} />;
    } else {
      return <h2>请先登陆</h2>;
    }
  };
}

export default loginAuth;
  • 构建 APP.jsx
javascript 复制代码
import React, { PureComponent } from "react";
import Cart from "./Cart";

export class App extends PureComponent {
  constructor() {
    super();

    this.state = {
      isLogin: false,
    };
  }

  loginClick() {
    localStorage.setItem("token", "test token value");
    this.setState({
      isLogin: true,
    });
  }

  render() {
    const { isLogin } = this.state;

    return (
      <div>
        <button onClick={(e) => this.loginClick()}>登录</button>
        <Cart />
      </div>
    );
  }
}

export default App;
  • 构建Cart.jsx,并用loginAuth包裹Cart进行鉴权处理
javascript 复制代码
import React, { PureComponent } from "react";
import loginAuth from "./login_auth";

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

export default loginAuth(Cart);

高阶组件的应用场景(四)------ 打印界面渲染时间

  • 构建打印界面渲染时间高阶组件
javascript 复制代码
import { PureComponent } from "react";

function logRenderTime(OriginComponent) {
  return class extends PureComponent {
    UNSAFE_componentWillMount() {
      this.beginTime = new Date().getTime();
    }

    componentDidMount() {
      this.endTime = new Date().getTime();
      const interval = this.endTime - this.beginTime;
      console.log(`当前页面:${OriginComponent.name} 的渲染花费:${interval} ms`);
    }

    render() {
      return <OriginComponent />;
    }
  };
}

export default logRenderTime
  • 构建App.jsx
javascript 复制代码
import React, { PureComponent } from 'react'
import Detail from './Detail'

export class App extends PureComponent {
  render() {
    return (
      <div>
       
        <Detail></Detail>
      </div>
    )
  }
}

export default App
  • 构建Detail.jsx,并通过logRenderTime拦截Detail组件,打印其界面渲染时间
javascript 复制代码
import React, { PureComponent } from "react";
import logRenderTime from "./log_render_time";

export class Detail extends PureComponent {
  render() {
    return (
      <div>
        <h2>Detail Page</h2>
        <ul>
          <li>数据列表1</li>
          <li>数据列表2</li>
          <li>数据列表3</li>
          <li>数据列表4</li>
          <li>数据列表5</li>
          <li>数据列表6</li>
          <li>数据列表7</li>
          <li>数据列表8</li>
          <li>数据列表9</li>
          <li>数据列表10</li>
        </ul>
      </div>
    );
  }
}

export default logRenderTime(Detail);
相关推荐
0思必得09 分钟前
[Web自动化] 开发者工具性能(Performance)面板
运维·前端·自动化·web自动化·开发者工具
心灵的制造商14 分钟前
el-tree左侧新增类别和删除类别实例代码
前端·javascript·vue.js
爱吃无爪鱼16 分钟前
01-前端开发快速入门路线图
javascript·css·vue.js·typescript·前端框架·npm·node.js
冴羽16 分钟前
不知道怎么写 Nano Banana Pro 提示词?分享你一个结构化示例,复刻任意图片
前端·人工智能·aigc
IT_陈寒17 分钟前
JavaScript 性能优化:7个 V8 引擎隐藏技巧让你的代码提速200%
前端·人工智能·后端
脾气有点小暴23 分钟前
uniapp通用单张图片上传组件
前端·javascript·vue.js·uni-app·uniapp
小菜今天没吃饱29 分钟前
DVWA-XSS(stored)
前端·网络安全·xss·dvwa
云飞云共享云桌面29 分钟前
研发部门使用SolidWorks,三维设计云桌面应该怎么选?
运维·服务器·前端·网络·自动化·电脑
老华带你飞38 分钟前
茶叶商城|基于SprinBoot+vue的茶叶商城系统(源码+数据库+文档)
java·前端·javascript·数据库·vue.js·spring boot
烛阴40 分钟前
不只是Public与Private:C#访问修饰符全方位解读
前端·c#