react学习—高阶组件HOC

本文介绍了React中的高阶组件(HOC)概念,通过实例展示了如何创建和使用高阶组件,包括属性传递和条件渲染。HOC能够提高代码复用性和维护性,用于实现如日志记录、登录检查等复杂逻辑。注意,避免在render函数中动态创建高阶组件以防止不必要的组件重建,影响性能。

一、高阶组件HOC

HOF:Higher-Order Function, 高阶函数,以函数作为参数,并返回一个函数,例如(compose、bind)
HOC: Higher-Order Component, 高阶组件,以组件作为参数,并返回一个组件。
如下例代码B,返回一个新的组件,所以B就是一个高阶组件。

import React from 'react'

export default function withTest(comp) {
  return class extends React.Component{

  }
}
function A(){
  return <h1>test</h1>
}
const B = withTest(A);

1.高阶组件

如果我们要设计一个日志记录组件,那么想想怎样能让这个日志记录组件复用性更高,后期更好维护呢?将整个日志记录组件封装成一个组件?

//withLog.js
import React from 'react'

export default function withLog(Comp) {// 使用传入的记录器组件进行记录
  return class LogWarpper extends React.Component {// 取个名字方便后期调试
    componentDidMount() {
      console.log(`日志:组件${Comp.name}被创建了!${Date.now()}`);
    }

    componentWillUnmount() {
      console.log(`日志:组件${Comp.name}被销毁了!${Date.now()}`);
    }
    render(){
      return <Comp />
    }
  }
}

如下两个记录器A、B,如果想实现两个记录器,那么难以避免造成代码重复,索性交给另一个组件专门去实现如何进行记录,然后调用A,B即可。

//Comp.js
import React from 'react'
export class A extends React.Component{// A记录器
  render() {
    return <h1>A</h1>
  }
}
export class B extends React.Component{// B记录器
  render() {
    return <h1>B</h1>
  }
}
import React, { Component } from 'react'
import {A,B} from './components/Comps'
import withLog from './HOC/withLog'

const ALog = withLog(A);
const BLog = withLog(B);
export default class Input extends Component {
  render() {
    return (
      <div>
        <ALog />
        <BLog />
      </div>
    )
  }
}

这里就很明显了,A,B只会记录事件,如何记录是LogWarpper的事;两个组件分开也能实现一些功能,组合起来则能产生1+1>2的效果。
在这里插入图片描述
在这里插入图片描述

2、属性传递

组件通过嵌套,那么属性当然也需要我们自己手动一层一层向下传递。

//withLog.js
import React from 'react'

export default function withLog(Comp) {
  return class LogWarpper extends React.Component {
    componentDidMount() {
      console.log(`日志:组件${Comp.name}被创建了!${Date.now()}`);
    }

    componentWillUnmount() {
      console.log(`日志:组件${Comp.name}被销毁了!${Date.now()}`);
    }
    render(){
      return <Comp {...this.props} />
    }
  }
}
//Comps.js
import React from 'react'
export class A extends React.Component{
  render() {
    return <h1>A:{this.props.a}</h1>
  }
}
export class B extends React.Component{
  render() {
    return <h1>B:{this.props.b}</h1>
  }
}
import React, { Component } from 'react'
import {A,B} from './components/Comps'
import withLog from './HOC/withLog'

const ALog = withLog(A);
const BLog = withLog(B);
export default class Input extends Component {
  render() {
    return (
      <div>
        <ALog a={'a'} />
        <BLog b={'b'} />
      </div>
    )
  }
}

在这里插入图片描述
在这里插入图片描述

3、使用属性传递

模拟一个登录系统,只有当提取到登录信息isLogin后才能显示后续页面。

//withLogin
import React from 'react'

export default function withLogin(Comp) {
  return function LoginWrapper(props) {
    if(props.isLogin){
      return <Comp {...props} />
    }
    return null;
  }
}

Comp并未有任何改变

//Comp.js
import React from 'react'
export class A extends React.Component{
  render() {
    return <h1>A:{this.props.a}</h1>
  }
}
export class B extends React.Component{
  render() {
    return <h1>B:{this.props.b}</h1>
  }
}

如果不传isLogin

import React, { Component } from 'react'
import {A,B} from './components/Comps'
import withLogin from './HOC/withLogin'

const ALog = withLogin(A);
const BLog = withLogin(B);
export default class Input extends Component {
  render() {
    return (
      <div>
        <ALog a={'a'} />
        <BLog b={'b'} />
      </div>
    )
  }
}

在这里插入图片描述
传入isLogin后
在这里插入图片描述
是不是发现高阶组件的用处大大的了?其用处当然不止如此,还可以配合我们实现各种复杂的逻辑。

4、注意

如果我们render函数内去包装一个高阶组件呢?

import React, { Component } from 'react'
import {A,B} from './components/Comps'
import withLog from './HOC/withLog'

export default class Input extends Component {
  render() {
    const ALog = withLog(A);
    const BLog = withLog(B); 
    return (
      <div>
        <ALog isLogin a={'a'} />
        <BLog isLogin b={'b'} />
        <button onClick={()=>{
          this.setState({})
        }}>点击</button>
      </div>
    )
  }
}

在这里插入图片描述
一旦我们对状态进行操作时,你会发现,组件并没有进行重用单独刷新数据,而是整个组件都销毁冲建了。这会对性能造成影响。
此外不要在高阶组件内部更改传入的组件
在这里插入图片描述
博主开始运营自己的公众号啦,感兴趣的可以关注“飞羽逐星”微信公众号哦,拿起手机就能阅读感兴趣的博客啦!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飞羽逐星

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值