1. 概念

高阶组件和高阶函数的类似,使用函数接收一个组件,并返回一个组件。

function withList(WrapComponent) {return class extends Component {render() {return <div><WrapComponent {...this.props}/></div>;}}
};

高阶组件主要用作于逻辑的封装、拦截渲染、拦截生命周期:获取渲染性能,日志打点等,安按照实现方式可以分为属性代理和反向继承两种。

2. 属性代理

属性代理的作用:

  • 代理props
  • 条件渲染
  • 添加状态(state)
  • 封装一些通用的逻辑

2.1 代理props

function withList(WrapComponent) {const data = [{ id: '1', text: '测试1' }, { id: '2', text: '测试2' }, { id: '3', text: '测试3' }, { id: '4', text: '测试4' }, { id: '5', text: '测试5' }]return class extends Component {render() {return <div>{this.props.data.length > 0 ? <WrapComponent {...this.props} data={data} /> : <span>{emptyText}</span>}</div>;}}
};class List extends Component {render() {return (<ul>{this.props.data.map(item => {return <li key={item.id}>{item.text}</li>})}</ul>)}
};export default withList(List);

2.2 条件渲染

function withList(WrapComponent, emptyText) {return class extends Component {render() {return <div>{this.props.data.length>0 ? <WrapComponent {...this.props}/> : <span>{emptyText}</span>}</div>;}}
};class List extends Component {render() {return (<ul>{this.props.data.map(item => {return <li key={item.id}>{item.text}</li>})}</ul>)}
};export default withList(List,'暂无数据');

2.3 添加状态
利用这一点可以将非受控组件转为受控组件

import React, { Component } from 'react'class Input extends Component {render() {return (<input value={this.props.value} />)}
};function withInput(WrapComponent) {return class extends Component {state = {value: this.props.value}onChange = (value) => {this.setState({ value });}render() {return <WrapComponent {...this.props} value={this.state.value} onChange={this.onChange}/>;}}
};export default withInput(Input);

3. 反向继承

反向继承的作用

  • 拦截渲染
  • 代理props
  • 劫持生命周期函数
  • 操作state
  • 修改react树

3.1 拦截渲染

function withList(WrapComponent) {return class extends WrapComponent {render() {return <div><span>通过反向继承拦截渲染</span>{super.render()}</div>;}}
};

3.2 劫持生命周期

function withList(WrapComponent) {return class extends WrapComponent {componentDidMount(){if(super.componentDidMount){super.componentDidMount.apply(this);};console.log('拦截生命周期');}render() {return <div><span>通过反向继承拦截渲染</span>{super.render()}</div>;}}
};

3.3 操作state

import React, { Component } from 'react';function withList(WrapComponent) {return class extends WrapComponent {constructor(props) {super(props);this.state.data = []; //将列表数据置空}render() {return <div>{super.render()}</div>}}
};class List extends Component {state = {data: [{ id: '1', text: '测试1' }, { id: '2', text: '测试2' }, { id: '3', text: '测试3' }, { id: '4', text: '测试4' }, { id: '5', text: '测试5' }],}render() {return (<ul>{this.state.data.map(item => {return <li key={item.id}>{item.text}</li>})}</ul>)}
};export default withList(List);

3.4 修改react树


import React, { Component } from 'react';function withList(WrapComponent) {return class extends WrapComponent {render() {const tree = super.render();let newProps = { ...tree.props };if (tree.type === 'ul') {newProps.value = 'value';}return React.cloneElement(tree, newProps, newProps.children);}}
};class List extends Component {render() {return (<ul>{this.props.data.map(item => {return <li key={item.id}>{item.text}</li>})}</ul>)}
};export default withList(List);

3.5 记录渲染性能

function withTime(WrapComponent) {return class extends WrapComponent {constructor(props) {super(props);this.start = 0;this.end = 0}componentWillMount() {if (super.componentWillMount) {super.componentWillMount.call(this);};this.start = Date.now();}componentDidMount() {if (super.componentDidMount) {super.componentDidMount.call(this);};this.end = Date.now();console.log(`渲染的时间为:${(this.end - this.start) / 1000}秒`)}render() {return super.render();}}
};

4. 使用装饰器

4.1 安装和配置
首先执行npm run eject暴露出webpack配置,然后安装装饰器插件

yarn add  @babel/plugin-proposal-decoreators;

最后在package.json中的babel配置中添加一下配置然后重新项目

  "babel": {"presets": ["react-app"],"plugins":[["@babel/plugin-proposal-decorators",{"legacy":true}]]}

配置完之后如果有报红需要配置一下:
文件-> 首选项 -> 搜索 ExperimentalDecorators 勾选上之后红线就消失了

4.2 使用

@withList
class List extends Component {render() {return (<ul>{this.props.data.map(item => {return <li key={item.id}>{item.text}</li>})}</ul>)}
};

5.总结

  • 高阶组件的作用有代复用、代理属性、拦截渲染、劫持生命周期
  • 反向继承能直接操作和拦截组件的state和生命周期,功能比属性代理更加强大

React的高阶组件(HOC)相关推荐

  1. [react] 使用高阶组件(HOC)实现一个loading组件

    [react] 使用高阶组件(HOC)实现一个loading组件 function HOC(wrappedComponent) {return class extends React.Componen ...

  2. react学习—高阶组件HOC

    高阶组件HOC 一.高阶组件HOC 1.高阶组件 2.属性传递 3.使用属性传递 4.注意 一.高阶组件HOC HOF:Higher-Order Function, 高阶函数,以函数作为参数,并返回一 ...

  3. React Native高阶组件(HOC)模型理论与实践

    什么是HOC? HOC(全称Higher-order component)是一种React的进阶使用方法,主要还是为了便于组件的复用.HOC就是一个方法,获取一个组件,返回一个更高级的组件. 什么时候 ...

  4. [react] 高阶组件(HOC)有哪些优点和缺点?

    [react] 高阶组件(HOC)有哪些优点和缺点? HOC 优点 通过传递props去影响内层组件的状态,不直接改变内层组件的状态,降低了耦合度 缺点 组件多层嵌套, 增加复杂度与理解成本 ref隔 ...

  5. [react] 举例说明什么是高阶组件(HOC)的反向继承

    [react] 举例说明什么是高阶组件(HOC)的反向继承 import React from 'react';const hoc = (WrappedComponent) => {// 集成需 ...

  6. [react] 举例说明什么是高阶组件(HOC)的属性代理

    [react] 举例说明什么是高阶组件(HOC)的属性代理 function HOC(WrappedComponent) {return class HOC extends Component {re ...

  7. 「react进阶」一文吃透React高阶组件(HOC)

    一 前言 React高阶组件(HOC),对于很多react开发者来说并不陌生,它是灵活使用react组件的一种技巧,高阶组件本身不是组件,它是一个参数为组件,返回值也是一个组件的函数.高阶作用用于强化 ...

  8. React 高阶组件HOC使用总结

    HOC(高阶组件) /*HOC(高阶组件): 接收一个组件,返回包装后的组件(增强组件)- 不是React API- 是一种设计模式,类似于装饰器模式- ≈ Mixin && > ...

  9. react 高阶组件hoc使用

    react 高阶组件hoc使用 1. 为什么使用高阶组件 2. 具体使用 2.1原代码: 2.2 使用hoc封装后 1. 为什么使用高阶组件 高阶组件(HOC)是 React 中用于复用组件逻辑的一种 ...

最新文章

  1. Eclipse SVN冲突详细解决方案
  2. 戴尔r720服务器增加内存,dell r720服务器加了一根内存后,开机显示configuring memory,卡在这里进不了系统,请问这是什么情况?...
  3. [转载](热议)“我不伟大”,但可以让善良“春暖花开”
  4. Android书页翻页设计:android-flip
  5. Oculus cv1 input
  6. 北京理工大学计算机学院研究生培养方案,北京理工大学2018版学术型研究生培养方案.PDF...
  7. python flask服务器假死_python – Flask POST请求导致服务器崩溃
  8. libz.so.1: cannot open shared object file: No such file or directory
  9. 增加批量修改成本价格,配合后台管理增加成本价和毛利润统计
  10. C#Winform使用火狐firefox内核GeckoWebBrowser
  11. 浅析企业上下级沟通的障碍及对策
  12. 【Web】lighttpd基础
  13. 地图图像迁移研究与实现
  14. 视频剪辑 - Pr入门[第一次学习] - 小白蜕变!!!
  15. 递推数列【清华大学】
  16. 其他算法和思想的题目
  17. javascript学习路线图
  18. 一个好用的流氓软件清理工具合集
  19. 聊QQ时,系统消息提示“被迫下线”怎么回事
  20. INTEL CPU型号详解分类:电脑硬件

热门文章

  1. 100层楼和两个玻璃球思路解析
  2. google 浏览器迅雷支持
  3. js超好懂的螺旋矩阵解法(用递归)
  4. 华为防火墙重启_华为防火墙常用命令
  5. pixhawk入门指南
  6. for do done重定向
  7. 池州学院数学计算机科学,池州学院数学与计算机科学系
  8. 两步解决SQL yog 试用到期问题
  9. 看涨/看跌期权价格曲线
  10. Spring自动装配通俗易懂的解释