【React】HOC 高阶组件

高阶组件

  • Higher-Order Components就是一个函数,传给它一个组件(参数是组件),它返回一个新的组件(返回值是组件)
  • 作用:对原有的组件的扩展
const NewComponent = higherOrderComponent(YourComponent)
  • 比如,我们想要我们的组件通过自动注入一个版权信息。
  • withCopyright.jsx 文件定义一个高阶组件
//版权的高阶组件 hoc 
import React, { Component } from 'react';
//参数: 组件
const withCopy = (WrappedComponent) => {
    //返回一个新组件
    return class NewComponent extends Component {
        render() {
            return (
                <>
                    {/*  {...this.props} 将 App的props的值接收并解构 */}
                    <WrappedComponent title="版权信息"  {...this.props} />
                    <div>&copy; 版权所有:LS</div>
                </>
            )
        }

    }
}
export default withCopy;
  • App.jsx组件使用方式
import React,{Component} from 'react';
// 引入高阶组件
import withCopy from './withCopy';
class App extends Component{
    constructor(props){
        super(props);
        this.state = {};
    }
    componentDidMount(){
        console.log(this.props);
    }
    render(){
        return (<>
        	根节点
        </>)
    }
}
export default withCopy(App);

  • index.js文件 在App调用上传了参数
import ReactDOM  from 'react-dom'
import App from './HOC/App';

ReactDOM.render(
    <App msg='3' />,
    document.getElementById('root')
)

在这里插入图片描述

  • 这样只要我们有需要用到版权信息的组件,都可以直接使用withCopyright这个高阶组件包裹即可。

应用场景

  1. 进行权限判断:
    页面中的按钮权限,在高阶组件中实现权限判断,页面权限判断,进行路由跳转
  2. 日志记录:
    逻辑提取出来,封装成高阶组件,如果哪个组件需要进行日志处理,在组件名的外面包裹一层日志高阶组件
  3. 数据校验:
    多个地方都需要进行校验数据,将逻辑拆出来,封装成高阶组件
  4. 异常处理:
    进行封装异常处理,例如:异常时来个弹窗报错
  • 高阶组件实例:权限判断
  • 需求:一个admin(管理员),一个user(普通用户)
  • 要求:管理员进入页面,按钮就可见,普通用户进页面,按钮不可见
  • 使用高阶组件解决这种需求经常变化,而且多个地方都需要鉴权的情况

  • withAuth.jsx文件
//作用 ,判断权限,返回是否有权限的按钮信息
import React, { Component } from 'react';
const withAuth = (WrappedComponent) => {
    //返回一个新组件
    return class NweComponent extends Component {
        render() {
            if (this.props.author === "admin") {
                return <WrappedComponent {...this.props} />
            } else {
                return null;
            }
        }

    }
}
export default withAuth;
  • Button.jsx文件
//按钮组件
import React, { Component } from 'react';
import withAuth from './withAuth';

class Button extends Component {
    constructor(props) {
        super(props);
        this.state = {}
    }
    render() {
        return (<button >{this.props.children}</button>);
    }
}

export default withAuth(Button);
  • App.jsx文件
import React, { Component } from 'react';
import Button from './Button';
//模拟权限用户数据
function getAuthor() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            //取个0-1之间的随机数
            let index = Math.round(1 - Math.random());
            let author = ['admin', 'user'][index];
            resolve(author)
        }, 1000)
    })
}
class App extends Component {
    constructor(props) {
        super(props);
        this.state = {
            author: ''
        }
    }
    async componentDidMount() {
        let author = await getAuthor();
        this.setState({ author: author })
    }
    render() {
        const { author } = this.state;
        return (
            <div>
                <h1>欢迎 {author} 登录本系统!!</h1>
                <Button author={author}>新增用户</Button>
                <Button author={author}>删除用户</Button>
                <Button author={author}>修改用户密码</Button>
                <Button author={author}>冻结用户</Button>
            </div>
        );
    }
}
export default App;
  • index.js文件
import ReactDOM  from 'react-dom'
import App from './HOC/App';

ReactDOM.render(
    <App  />,
    document.getElementById('root')
)
  • 刷新页面
    在这里插入图片描述
    在这里插入图片描述

高阶组件的特点:

  1. 高阶组件就是把某个组件装饰成一个新的组件,对功能进行了扩展
  2. 高阶组件进行了代码复用,封装,有利于解耦,增强了灵活性
  3. 核心思想:装饰器模式
    装饰器是ES7的语法:可以对类、方法属性进行包装,包装后就在原有的基础上增加了一些新特性
    高阶组件,装饰的对象是一个类
  • 需要先配置文件,才能使用装饰器
  • 配置教程请参考我的另一篇博客
  • 使用装饰器重新Button.jsx文件
//按钮组件
import React, { Component } from 'react';
import withAuth from './withAuth';
//装饰器的语法更优雅
@withAuth
class Button extends Component {
    constructor(props) {
        super(props);
        this.state = {}
    }
    render() {
        return (<button >{this.props.children}</button>);
    }
}

export default Button;
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

一颗不甘坠落的流星

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

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

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

打赏作者

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

抵扣说明:

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

余额充值