React高阶组件

为什么要使用高阶组件?

想想以前用原生和jQuery的项目,上千行的code映入眼帘,瞬间有种昏死过去的冲动。代码难以维护,改一个bug可能出现N个bug,真的是很痛苦。于是乎组件化成为了当前前端开发的主流技术。angular、vue和react很好的帮我们实现了组件化。

但是我们常常也会遇到一种情况,就是两个组件往往有很多的重复代码(可能是相同的属性,也可能是相同的方法)。例如,在登录和注册组件中,都会有用户名和密码,以及对他们的校验规则。为了提高代码的复用性和可维护性,React高阶函数应运而生。

React之前对此的解决方案是mixin,但这造成和很多不必要的问题,后来就被废弃掉了。使用过vue的同学,不知道有没有使用过mixin,react高阶函数的作用和它是一样的。

高阶组件到底是个什么东西?

高阶组件其实是一个函数,它并不是一个组件,我们需要向它传递一些参数(想要操作的组件、属性)。这么说起来它其实一点也不高阶,它的作用就是存储一些公共的属性和方法。

我们经常几个人吃过一个锅底的那种火锅,锅底里有火锅底料和各种佐料,我们把肉和蔬菜等放进去涮一下,就可以美美的饱餐一顿。高阶函数在react编程中扮演的角色就是火锅锅底的角色,它有公用的方法和属性,而各种组件就是肉和蔬菜。如果是一个人一个锅的火锅就像没有经过封装的code,代码量重复且维护困难。

如何实现高阶函数?

我们先来看一段可以使用高阶函数的代码:

import React from 'react';


class Second extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            username: ''
        }
    }
    componentWillMount() {
        let username = localStorage.getItem('username');
        this.setState({
            username: username
        });
    }
    render() {
        return(
            <div>
                <legend>Second Page</legend>
                <h2>Hi {this.state.username}</h2>
            </div>
        )
    }
}
export default Second;

下面是一个Third组件,它也负责展示用户名

import React from 'react';

class Third extends React.Component{
    constructor (props){
        super(props);
        this.state = {
            username: ''
        }
    }

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

    render (){
        return(
            <div>
                <legend>Third Page</legend>
                <h2>Hi {this.state.username}</h2>
                <p>我今年18岁了</p>
            </div>
        );
    }
}

export default Third;

我们看到这两个组件除了名称以外,其余大量的代码是一样的,我们完全可以考虑将它们通用的代码提取出来。下面就是高阶组件出场的时候了。

高阶组件可以写成这样

import React from 'react';

const HighOrderComponent = (WrapComponent, title) =>{
    return class HOC extends React.Component{
        constructor(props){
            super(props);
            this.state = {
                username: ''
            }
        }

        componentWillMount() {
            let username = localStorage.getItem('username');
            this.setState({
                username: username
            });
        }
       
        render() {
            return(
                <div>
                    <legend>{title}</legend>
                    <WrapComponent username={this.state.username}></WrapComponent>
                </div>
            )
        }
    }
}

export default HighOrderComponent;
  • WrapComponent 是我们要操作的组件
  • title 是它们的标题参数
  • username 就是我们常用的props,它负责向组件传递值,我们下面还会提到
  • 使用高阶组件之后我们要对Second和Third组件进行修改,修改如
import React from 'react';
import HighOrderComponent from './HighOrderComponent.jsx';

class SecHoc extends React.Component{
    render(){
        return (
            <div>
                <h2>Hi </h2>
                <h2>晓不晓得哪里好耍{this.props.username}</h2>
            </div>
        );
    }
}




const HighOrderSecond = HighOrderComponent(SecHoc, 'Second Page');

export default HighOrderSecond;

很多同学可能会问,export出去的常量是干什么用的,它就是高阶组件对组件进行封装之后的一个全新的组件,是两者的结合。到此,我们在其它页面引用组件就不再是引用Second和Third组件了,要引用的就是HighOrderSecond和HighOrderThird了。

细心的同学可能会发现一些不同的地方,对于Second和Third的公共legend提取出去了,但并没有将h2对应得标题提取出去,这里只是想给大家说一下,在对组件使用高阶组件包裹之后,高阶组件就变成了组件的父组件,它的state可以通过props的方式向子组件传递,username就是这样。我们在chrome的react插件中可以观察到这一点

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值