React中高阶组件应用

2023-10-30

高阶组件:函数传入一个组件,返回一个新的组件。
1、高阶组件的运用:
在不破坏原本的结构的时候,利用高阶组件进行加工。
如下,如果要在Home组件以及About组件再传入region=“中国”,就需要两个都修改。

class App extends PureComponent {
  render() {
    return (
      <div>
        App
        <Home nickname="coderwhy" level={90}/>
        <About nickname="kobe" level={99}/>
      </div>
    )
  }
}

export default App;

使用高阶组件进行加工操作:

// 定义一个高阶组件
function enhanceRegionProps(WrappedComponent) {
  return props => {
    return <WrappedComponent {...props} region="中国"/>
  }
}
class App extends PureComponent {
  render() {
    return (
      <div>
        App
        <EnhanceHome nickname="coderwhy" level={90}/>
        <EnhanceAbout nickname="kobe" level={99}/>
      </div>
    )
  }
}

export default App;

2、增强props
可以利用高阶组件简化,例如下未简化共享数据context操作如下:
在其中,Home组件以及About组件有重复性代码。

// 创建Context
const UserContext = createContext({
  nickname: "默认",
  level: -1,
  region: "中国"
});
class Home extends PureComponent {
  render() {
    return (
      <UserContext.Consumer>
        {
          user => {
            return <h2>Home: {`昵称: ${user.nickname} 等级: ${user.level} 区域: ${user.region}`}</h2>
          } 
        }
      </UserContext.Consumer>
    )
  }
}

class About extends PureComponent {
  render() {
    return (
      <UserContext.Consumer>
        {
          user => {
            return <h2>About: {`昵称: ${user.nickname} 等级: ${user.level} 区域: ${user.region}`}</h2>
          } 
        }
      </UserContext.Consumer>
    )
  }
}

class App extends PureComponent {
  render() {
    return (
      <div>
        App
        <UserContext.Provider value={{nickname: "why", level: 90, region: "中国"}}>
          <Home/>
          <About/>
        </UserContext.Provider>
      </div>
    )
  }
}

export default App;

创捷高阶组件,进行简化:

// 定义一个高阶组件
function withUser(WrappedComponent) {
  return props => {
    return (
      <UserContext.Consumer>
        {
          user => {
            return <WrappedComponent {...props} {...user}/>
          } 
        }
      </UserContext.Consumer>
    )
  }
}

// 创建Context
const UserContext = createContext({
  nickname: "默认",
  level: -1,
  区域: "中国"
});

class Home extends PureComponent {
  render() {
    return <h2>Home: {`昵称: ${this.props.nickname} 等级: ${this.props.level} 区域: ${this.props.region}`}</h2>
  }
}


class About extends PureComponent {
  render() {
    return <h2>About: {`昵称: ${this.props.nickname} 等级: ${this.props.level} 区域: ${this.props.region}`}</h2>
  }
}

class Detail extends PureComponent {
  render() {
    return (
      <ul>
        <li>{this.props.nickname}</li>
        <li>{this.props.level}</li>
        <li>{this.props.region}</li>
      </ul>
    )
  }
}


const UserHome = withUser(Home);
const UserAbout = withUser(About);
const UserDetail = withUser(Detail);

class App extends PureComponent {
  render() {
    return (
      <div>
        App
        <UserContext.Provider value={{nickname: "why", level: 90, region: "中国"}}>
          <UserHome/>
          <UserAbout/>
          <UserDetail/>
        </UserContext.Provider>
      </div>
    )
  }
}

export default App;

3、高阶组件实现简单的登录鉴权操作
使用高阶组件进行判断是否是登陆状态再确定返回显示的组件。
其中的 NewCpn.displayName = "AuthCpn"是修改组件名。

import React, { PureComponent } from 'react';

class LoginPage extends PureComponent {
  render() {
    return <h2>LoginPage</h2>
  }
}

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

  NewCpn.displayName = "AuthCpn"

  return NewCpn;
}

// 购物车组件
class CartPage extends PureComponent {
  render() {
    return <h2>CartPage</h2>
  }
}

const AuthCartPage = withAuth(CartPage);

export default class App extends PureComponent {
  render() {
    return (
      <div>
        <AuthCartPage isLogin={true}/>
      </div>
    )
  }
}

4、高阶组件生命周期劫持
实现渲染时间的计算。

function withRenderTime(WrappedComponent) {
  return class extends PureComponent {
    // 即将渲染获取一个时间 beginTime
    UNSAFE_componentWillMount() {
      this.beginTime = Date.now();
    }

    // 渲染完成再获取一个时间 endTime
    componentDidMount() {
      this.endTime = Date.now();
      const interval = this.endTime - this.beginTime;
      console.log(`${WrappedComponent.name}渲染时间: ${interval}`)
    }

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

class Home extends PureComponent {
  render() {
    return <h2>Home</h2>
  }
}


class About extends PureComponent {
  render() {
    return <h2>About</h2>
  }
}

const TimeHome = withRenderTime(Home);
const TimeAbout = withRenderTime(About);

export default class App extends PureComponent {
  render() {
    return (
      <div>
        <TimeHome />
        <TimeAbout />
      </div>
    )
  }
}

class Person {

}

console.log(Person.name);

5、高阶组件之ref的转发
ref不能运用于函数式组件,函数式组件没有实例,所以不能获取到对应的组件对象。
如果想要获取函数式组件之中的某个DOM元素,可以使用高阶组件forwardRef.
下面是按照props属性的方法思维,但是是错误的,ref是由react底层进行管理的。props没有ref.

function Profile(props) {
  return <p ref={props.ref}>Profile</p>
})
export default class App extends PureComponent {
  constructor(props) {
    super(props);
    this.profileRef = createRef();
  }

  render() {
    return (
      <div>
        <Profile ref={this.profileRef} name={"why"}/>

        <button onClick={e => this.printRef()}>打印ref</button>
      </div>
    )
  }

  printRef() {
    console.log(this.profileRef.current);
  } 
}

使用高阶组件forwardRef,组件代码修改为:
forwardRef让函数组件有第二个参数,ref

// 高阶组件forwardRef
const Profile = forwardRef(function(props, ref) {
  return <p ref={ref}>Profile</p>
})

6、Portals的使用
某些情况下,渲染内容独立于父组件,甚至独立于当前挂载到的DOM元素中。就例如实现一个位于页面中间的组件,独立于其父组件,虽然代码位置写在父组件内但是挂载在DOM元素之中。
使用ReactDOM.createPortal(),第一个参数是子元素,第二个参数是挂载的DOM元素。代码如下:
其中的 组件就是要放于页面中间的组件。this.props.children是第一个参数,代表的是组件之中包含的内容。

import React, { PureComponent } from 'react';
import ReactDOM from 'react-dom';

class Modal extends PureComponent {
  render() {
    return ReactDOM.createPortal(
      this.props.children,
      document.getElementById("modal")
    )
  }
}

class Home extends PureComponent {
  render() {
    return (
      <div>
        <h2>Home</h2>
        <Modal>
          <h2>Title</h2>
        </Modal>
      </div>
    )
  }
}

export default class App extends PureComponent {
  render() {
    return (
      <div>
        <Home/>
      </div>
    )
  }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

React中高阶组件应用 的相关文章

随机推荐

  • linux添加用户设置密码和用户sudo权限

    下面全部为root权限下操作 添加用户 adduser 用户名 添加密码 passwd 用户名 输入密码 用户添加sudo权限需要修改 etc sudoers 配置 先增加sudoers写入权限 chmod w etc sudoers 然后
  • 使用PlantUml绘制逻辑时序图/波形图

    AgileWave已支持PlantUml在线画图 Git源码参见 https github com cc hook agileWave AgileWave介绍 1 AgileWave 一款时序图绘制神器 2 好消息 源码和验证工具已开源至G
  • web前端开发到底是自学还是去上培训班?

    web前端开发到底是自学还是去上培训班 纠结中 应届毕业生 软件技术专业 去年接触到web前端开发这个行业 但是迷迷糊糊的就知道HTML CSS JS 其他一无所知 就知道做网页加一些网页的动态效果 没有系统的学习 相应的用到就学 没用到的
  • mysql 数据库常用、比较有用的语句

    添加索引 alter table user add index id time index id createTime 删除索引 alter table user drop index id time index 删除多余的 误添加的重复数
  • Android 清除缓存

    获取本机上缓存文件大小 private String taskGetCacheSize long size 0 File file1 getCacheDir File file2 getFilesDir File files new Fil
  • 21个React性能优化技巧

    React 为高性能应用设计提供了许多优化方案 本文列举了其中的一些最佳实践 在以下场景中 父组件和子组件通常会重新渲染 在同一组件或父组件中调用 setState 时 从父级收到的 props 的值发生变化 调用组件中的 forceUpd
  • 引用 C C++

    引用 引用是一个别名 它的作用就是作为目标的别名而使用 对这个引用的改动 就是对目标的改动 定义 例如引用一个整型变量 int a 666 int ra a 引用运算符 与地址操作符使用相同的符号 虽然它们显然是彼此相关的 但它们又是不一样
  • 【Qt QAxObject】使用 QAxObject 高效任意读写 Excel 表

    1 用什么操作 Excel 表 Qt 的官网库中是不包含 Microsoft Excel 的操作库 关于对 Microsoft Excel 的操作库可选的有很多 包含基于 Windows 系统本身的 ActiveX Qt Xlsx xlsL
  • 【Java】基础类型之float(八)

    特征 float 数据类型是单精度 32位 符合IEEE 754标准的浮点数 float 在储存大型浮点数组的时候可节省内存空间 默认值是 0 0f 浮点数不能用来表示精确的值 如货币 float是浮点类型中的一种 以F或f结尾标识 如果不
  • Secrets of RLHF in Large Language Models Part I: PPO

    本文是LLM系列文章 针对 Secrets of RLHF in Large Language Models Part I PPO 的翻译 大型语言模型中RLHF的秘密 上 PPO 摘要 1 引言 2 相关工作 3 人类反馈的强化学习 4
  • 高端技能之教你学会iOS抓包以及Fiddler抓包软件的用法

    软件安装包在最下面 安装fiddler 一路无脑选是 配置 Tools gt Options 第一步 勾选Https Decrypt用于将网页的密文包解为明文包 第二步 勾选Allow的意思是允许手机手动代理之后可以连接 第三步 记住端口号
  • 座舱开发的“道”与“术”

    前言 近年来 随着汽车 新四化 浪潮的兴起 软件定义已成为产业共识 将深度参与到整个汽车的定义 开发验证销售以及服务全过程 一方面确保软件可升级 跨车型 软件甚至跨车企软件重用 另一方面对于硬来讲 要做到可扩展 可更换 甚至做到传感器的即插
  • 单词接龙

    单词接龙 是指一组单词序列 任何两个相邻的单词满足前一个单词的尾字母和后一个单词的首字母相同 接龙长度 接龙中所有单词长度之和 如单词 tea cat dog aid fish 可以形成单词接龙 cat tea aid dog 其中cat为
  • [转]Project2010简易操作指南

    本文转自 http ce sysu edu cn hope Item aspx id 68176 一 启动阶段 1 前期准备 1 新建项目文件 选择 File NewNew 菜单 选择项目模版 打开项目文件 看见任务表格后设定任务自动排期
  • 网络地址不在同一网段能通信吗

    ip地址不一样的主机只要是在同一个网段就可以直接通信 如果在同一网段IP地址相同就冲突了 如果是不同的网段 而且不能通过掩码使其在一个大网段里 那么是不可以直接通信的 在同一网段可以直接通信是通过广播传输的 如果不通网段的话 广播包就过不去
  • Signoff Criteria --- ocv/aocv/pocv之POCV介绍

    POCV parametric on chip variation 本小节介绍pocv相关内容 1 Overview Process variation可以简单分成die to die和on chip variation ocv die t
  • 四级高频词汇360个

    英语四级高频词汇如下 1 alter v 改变 改动 变更 2 burst vi n 突然发生 爆裂 3 dispose vi 除掉 处置 解决 处理 of 4 blast n 爆炸 气流 vi 炸 炸掉 5 consume v 消耗 耗尽
  • 网络攻防WEB入门指南

    网络攻防WEB入门指南 大佬绕路 文章目录 前言 学习网络攻防该如何入门 前言 我对网络攻防的理解 分为比赛和实战两个部分 两者所学习的知识虽有共通之处 但还是有很大区别 我也在向实战的状态转换 不过二者入门所要掌握的知识差别不大 下面主要
  • 判断是否为子序列

    两个整数序列A a1 a2 a3 am和B b1 b2 b3 bn已存入两个单链表中 设计一个算法 判断 序列B是否是序列A的连续子序列 include
  • React中高阶组件应用

    高阶组件 函数传入一个组件 返回一个新的组件 1 高阶组件的运用 在不破坏原本的结构的时候 利用高阶组件进行加工 如下 如果要在Home组件以及About组件再传入region 中国 就需要两个都修改 class App extends P