【前端知识】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);
相关推荐
吃杠碰小鸡1 分钟前
高中数学-数列-导数证明
前端·数学·算法
kingwebo'sZone7 分钟前
C#使用Aspose.Words把 word转成图片
前端·c#·word
xjt_090126 分钟前
基于 Vue 3 构建企业级 Web Components 组件库
前端·javascript·vue.js
我是伪码农38 分钟前
Vue 2.3
前端·javascript·vue.js
夜郎king1 小时前
HTML5 SVG 实现日出日落动画与实时天气可视化
前端·html5·svg 日出日落
辰风沐阳1 小时前
JavaScript 的宏任务和微任务
javascript
夏幻灵2 小时前
HTML5里最常用的十大标签
前端·html·html5
冰暮流星2 小时前
javascript之二重循环练习
开发语言·javascript·数据库
Mr Xu_2 小时前
Vue 3 中 watch 的使用详解:监听响应式数据变化的利器
前端·javascript·vue.js
未来龙皇小蓝2 小时前
RBAC前端架构-01:项目初始化
前端·架构