【React】HOC

1 篇文章 0 订阅
本文深入探讨React高阶组件(HOC),包括其基本使用、修改props、控制渲染和渲染劫持等功能,并通过实例代码详细解析。HOC作为一种设计模式,用于在不破坏组件结构的情况下增强组件功能,实现逻辑复用。学习HOC有助于提升React应用的开发效率和代码质量。
摘要由CSDN通过智能技术生成

在网上针对HOC的深度好文很多,此文仅写给自己,一是记一记笔记,加深印象,二来也想谈谈自己的想法。
简而言之,HOC是对基础组件的再次包装,它可以劫持props、更改render,也可以做插件。和装饰器配合将现有的组件在不破坏结构的情况下添加内容,它也是一种设计模式,就像JS的工厂模式一样。将逻辑抽出来灵活复用。
如何使用呢?HOC有很多方式,这也是我学习了HOC迟迟不动手写博客的原因(过第一遍的时候一脸懵逼)先说最基础的方式吧。首先,写个简单的基础组件:

import React from 'react';

const Test2 = class extends React.Component {

  render() {

    return (
      <div>
        <input value={'hello world'} />
      </div>
    )
  }

}

export default Test2

然后,另起炉灶写HOC,在这里,为了区别,我在外层先加了hello:

export default function wapper(Wap) {
  return class extends React.Component {
    render() {
      return (
        <>
          <div>hello</div>
          <Wap />
        </>
      )
    }
  }
}

最后,在父组件中引用他们:

import React, { Component } from 'react';
import Hoc from './test';
import Test2 from './test2';

const Home = Hoc(Test2)

export default Home

现在,一个非常简单的HOC就写出来了:
在这里插入图片描述
或者,这么写HOC也可:

export default (PackagedComponent, props) =>
  class HOC extends React.Component {
    render() {
      return (
        <>
          <div>hello</div>
          <PackagedComponent />
        </>
      )
    }
  }

更多写法可以见这个博客:
React高阶组件(HOC)的写法归纳](https://blog.csdn.net/huolinianyu/article/details/89353256)

能够实现简单的后,就开始实现它的专有功能:
1、更改props
其实这个功能在组件之间传值的时候可能也用过,这里再单独说一下在HOC中如何修改props:
方法1:
如果是在引用的时候多给参数的方法,类似以下代码:

const Home = Hoc(Test2, value)

那么HOC是这么更改的:

export default (PackagedComponent, props) =>
  class HOC extends React.Component {
    render() {
      const newProps = {
        ...props,
        d: 0
      }
      return (
        <>
        ...
          <PackagedComponent value={newProps} />
        </>
      )
    }
  }

2、控制渲染
这个原理其实和修改props很像,在render中我们可以通过props传值,通过专属字段控制是否渲染:

 return (
        <>  
          {this.props.bol?<div>hello</div>:''}
          <PackagedComponent value={newProps} />
        </>
        )

3、渲染劫持
这部分十分的有趣,它的原理是HOC通过继承传入组件,修改传入组件的数值等达到渲染劫持的目的。
为了表述清除,我将传入组件、HOC、调用他们的组件(分开写的)全部贴出来。
传入组件:

const Test2 = class extends React.Component {
  render() {
    return (
	  <input value={'hello world'} />
    )
  }

}

HOC:

export default (PackagedComponent) =>
  class HOC extends PackagedComponent {

    render() {
      const tree = super.render()
      let newProps = {}
      if (tree && tree.type === `input`) {
        newProps = { value: "change" }
      }
      const newTree = React.cloneElement(tree, newProps)
      return newTree
    }
  }

调用组件

const Home = Hoc(Test2)
export default Home

最终效果:
在这里插入图片描述
打印出的新树结构:
在这里插入图片描述
看起来渲染劫持可以有效更改某个节点/多个节点的值,但是,需要注意一个点,这个点和ref注意的点很像,就是如果传入组件中包含另一个完整的组件,那么包含的那个组件不会被渲染劫持,下面用代码解释。
我将传入的Test2换成这样的写法:

const Test2 = class extends React.Component {
 render() {
    return (

      <div>
        <div>
          hello world
     </div>
        <Test3 />
      </div>
    )
  }
}

const Test3 = class extends React.Component {
  render() {
    return (
      <div>
        我是另一个组件
      </div>
    )
  }
}

HOC同样换个写法:

export default (PackagedComponent) =>
  class HOC extends PackagedComponent {

    render() {
      console.log(super.render())
      return super.render()
    }
  }

那么得到的结果如下图:
在这里插入图片描述
可以看到,完整的组件在劫持的时候不会返回详细的porps等信息。
渲染劫持的内容参考这篇文章

总结:HOC的学习大概写完了,文中没有提及的,是有大神用es7装饰器的写法写HOC,引用更加的方便。如果文中有问题,欢迎指正。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值