React系列之高阶组件

落落落洛克
• 阅读 1267

我的前端学习笔记📒

最近花了点时间把笔记整理到语雀上了,方便童鞋们阅读

React系列之高阶组件

React系列之高阶组件

背景

用到的原因是因为公司最近要做一个钉钉oa系统,选的技术栈则是比较火热的react,开发中遇到的问题就是代码如何复用问题,因为react官方已经不推荐使用Mixins,而是推荐了高阶组件这种方式,接下来我们就来聊聊它

高阶组件的概念

a higher-order component is a function that takes a component and returns a new component.

意思是:高阶组件是一个函数,它接受一个组件并返回一个新组件

利用函数带你理解高阶组件

举个例子🌰:假设我们现在需要实现一个登陆注册功能,为了方便,我们把用户(user)存在localStorage下,如果发生操作行为就会先去检测下有没有user (当然现实开发不可以这样做的)

代码实现:

// 登陆
  function login() {
    let user = localStorage.getItem('user');
    console.log('login ' + login);
}
// 注册
function resgister() {
    let user = localStorage.getItem('user');
    console.log('resgister ' + user);
}

login();
resgister();

上面的例子我们发现都有一句一模一样的冗余代码,这显然对于有代码洁癖的人简直不能忍,那就动手将它抽离出来挨打吧

代码实现:

// 登陆
  function login() {
    console.log('login ' + login);
}
// 注册
function resgister() {
    console.log('resgister ' + user);
}
// 抽离出来的中间函数
function wrapUser(Wrapfunc) {
    let Newfunc = () => {
       let user = localStorage.getItem('user');
       Wrapfunc(user);
    };
    return Newfunc;
}
// 调用
login = wrapUser(login);
resgister = wrapUser(resgister);
login();
resgister();

以上的例子我们可以把wrapUser称为高阶函数,它负责的是就是把我们共用代码抽离的出来,这样简化了复用的代码,很多同学会问,上面的代码量不是更加多了吗?但是实际开发项目时候复用的代码可不是这么一丁点,还有可能有其他需求产生复用这段代码就比如产品临时加了需要忘记密码的功能

代码如下:

 function forgetPassWord(){
    console.log('forgetPassWord ' + user);
 }
 forgetPassWord = wrapUser(forgetPassWord);
 forgetPassWord()

从高阶函数来看高阶组件

上面的代码如果用react方式是怎么实现的

Login组件

import React, {Component} from 'react'
class Login extends Component {
    constructor(props) {
        super(props);
        this.state = {
            user: ''
        }
    }

    componentWillMount() {
        let user = localStorage.getItem('user');
        this.setState({
            user
        })
    }

    render() {
        return (
            <div>login{this.state.user}</div>
        )
    }
}

export default Login;

Register组件

import React, {Component} from 'react'
class Register extends Component {
    constructor(props) {
        super(props);
        this.state = {
            user: ''
        }
    }
    componentWillMount() {
        let user = localStorage.getItem('user');
        this.setState({
            user
        })
    }
    render() {
        return (
            <div>register{this.state.user}</div>
        )
    }
}

export default Register;

可以看到这个组件这两个组件都有复用的代码,所以我们上述高阶函数wrapUser的例子来实现高阶组件

WrapUser高阶组件

import React, {Component} from 'react'

export default (WrapComponent) => {
    // 这里的WrapComponent是我们传进来的组件
    class NewComponent extends Component {
        constructor() {
            super();
            this.state = {
                user: ''
            }
        }

        componentWillMount() {
            let user = localStorage.getItem('user');
            this.setState({
                user
            })
        }

        render() {
            return <WrapComponent user={this.state.user}/>
        }
    }

    return NewComponent
}

上述的代码是声明一个函数这个函数从参数是接收一个组件,然后return回去一个新的组件,咋一看有同学发现这个很像是父组件套了一个子组件,没错实际上就是这样的,而且他们的通信也是父子组件通信

这样我们来简化下login组件和register组件

Login组件

import React, {Component} from 'react';
import WrapUser from 'WrapUser';

class Login extends Component {

    render() {
        return (
            <div>login{this.props.user}</div>
        )
    }
}

Login = WrapUser(Login);

export default Login;

Register组件

import React, {Component} from 'react';
import WrapUser from 'WrapUser';

class Register extends Component {

    render() {
        return (
            <div>register{this.props.user}</div>
        )
    }
}

Register = WrapUser(Register);

export default Register;

到这里我们代码复用性的问题就解决了,高阶组件实际就是一个函数,并不要被它的名称所吓倒

总结

  • 高阶组件的目的就是为了解决代码复用性问题
  • 高阶组件的通信是按照父子通信机制的

我的前端学习笔记📒

最近花了点时间把笔记整理到语雀上了,方便童鞋们阅读

React系列之高阶组件

React系列之高阶组件

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
落落落洛克 落落落洛克
3年前
写C端,如何优雅的处理多个弹框的显示?(附带源码)
我的前端学习笔记📒最近花了点时间把笔记整理到语雀上了,方便童鞋们阅读我的前端学习笔记📒(https://www.yuque.com/wanggangfeng
落落落洛克 落落落洛克
3年前
性能优化之防抖和节流
我的前端学习笔记📒最近花了点时间把笔记整理到语雀上了,方便童鞋们阅读我的前端学习笔记📒(https://www.yuque.com/wanggangfeng
落落落洛克 落落落洛克
3年前
React系列-自定义Hooks很简单(下)
我的前端学习笔记📒最近花了点时间把笔记整理到语雀上了,方便童鞋们阅读我的前端学习笔记📒(https://www.yuque.com/wanggangfeng
落落落洛克 落落落洛克
3年前
Redux系列之分析中间件原理(附经验分享)
我的前端学习笔记📒最近花了点时间把笔记整理到语雀上了,方便童鞋们阅读我的前端学习笔记📒(https://www.yuque.com/wanggangfeng
落落落洛克 落落落洛克
3年前
React系列-轻松学会Hooks(中)
我的前端学习笔记📒最近花了点时间把笔记整理到语雀上了,方便童鞋们阅读我的前端学习笔记📒(https://www.yuque.com/wanggangfeng
落落落洛克 落落落洛克
3年前
JavaScript进阶之实现拖拽(上)
我的前端学习笔记📒最近花了点时间把笔记整理到语雀上了,方便童鞋们阅读我的前端学习笔记📒(https://www.yuque.com/wanggangfeng
落落落洛克 落落落洛克
3年前
JavaScript进阶之new的实现
我的前端学习笔记📒最近花了点时间把笔记整理到语雀上了,方便童鞋们阅读我的前端学习笔记📒(https://www.yuque.com/wanggangfeng
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这