助你彻底理解React高阶组件(Higher-Order Components)

助你彻底理解React高阶组件(Higher-Order Components)

原文地址:https://github.com/brickspert... (若是你以为对你有帮助,请在github给个star~您的start是我不断创做的动力!)
原文不断更新,此处不维护。javascript

有时候人们很喜欢造一些名字很吓人的名词,让人一听这个名词就以为本身不可能学会,从而让人望而却步。可是其实这些名词背后所表明的东西其实很简单。来自React.js 小书css

高阶组件定义

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

翻译:高阶组件就是一个函数,且该函数接受一个组件做为参数,并返回一个新的组件。java

理解了吗?看了定义似懂非懂?继续往下看。react

函数模拟高阶组件

咱们经过普通函数来理解什么是高阶组件哦~git

  1. 最普通的方法,一个welcome,一个goodbye。两个函数先从localStorage读取了username,而后对username作了一些处理。github

function welcome() {
    let username = localStorage.getItem('username');
    console.log('welcome ' + username);
}

function goodbey() {
    let username = localStorage.getItem('username');
    console.log('goodbey ' + username);
}

welcome();
goodbey();
  1. 咱们发现两个函数有一句代码是同样的,这叫冗余唉。很差很差~(你能够把那一句代码理解成平时的一大堆代码)redux

    咱们要写一个中间函数,读取`username`,他来负责把`username`传递给两个函数。
function welcome(username) {
    console.log('welcome ' + username);
}

function goodbey(username) {
    console.log('goodbey ' + username);
}

function wrapWithUsername(wrappedFunc) {
    let newFunc = () => {
        let username = localStorage.getItem('username');
        wrappedFunc(username);
    };
    return newFunc;
}

welcome = wrapWithUsername(welcome);
goodbey = wrapWithUsername(goodbey);

welcome();
welcome();

好了,咱们里面的wrapWithUsername函数就是一个“高阶函数”。
他作了什么?他帮咱们处理了username,传递给目标函数。咱们调用最终的函数welcome的时候,根本不用关心username是怎么来的。antd

咱们增长个用户study函数。app

function study(username){
    console.log(username+' study');
}
study = wrapWithUsername(study);

study();

这里你是否是理解了为何说wrapWithUsername是高阶函数?咱们只须要知道,用wrapWithUsername包装咱们的study函数后,study函数第一个参数是username

咱们写平时写代码的时候,不用关心wrapWithUsername内部是如何实现的。

高阶组件

高阶组件就是一个没有反作用的纯函数。

咱们把上一节的函数通通改为react组件。

  1. 最普通的组件哦。

welcome函数转为react组件。

import React, {Component} from 'react'

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

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

    render() {
        return (
            <div>welcome {this.state.username}</div>
        )
    }
}

export default Welcome;

goodbey函数转为react组件。

import React, {Component} from 'react'

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

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

    render() {
        return (
            <div>goodbye {this.state.username}</div>
        )
    }
}

export default Goodbye;
  1. 如今你是否是更能看到问题所在了?两个组件大部分代码都是重复的唉。

按照上一节wrapWithUsername函数的思路,咱们来写一个高阶组件(高阶组件就是一个函数,且该函数接受一个组件做为参数,并返回一个新的组件)。

import React, {Component} from 'react'

export default (WrappedComponent) => {
    class NewComponent extends Component {
        constructor() {
            super();
            this.state = {
                username: ''
            }
        }

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

        render() {
            return <WrappedComponent username={this.state.username}/>
        }
    }

    return NewComponent
}

这样咱们就能简化Welcome组件和Goodbye组件。

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

class Welcome extends Component {

    render() {
        return (
            <div>welcome {this.props.username}</div>
        )
    }
}

Welcome = wrapWithUsername(Welcome);

export default Welcome;
import React, {Component} from 'react';
import wrapWithUsername from 'wrapWithUsername';

class Goodbye extends Component {

    render() {
        return (
            <div>goodbye {this.props.username}</div>
        )
    }
}

Goodbye = wrapWithUsername(Goodbye);

export default Goodbye;

看到没有,高阶组件就是把username经过props传递给目标组件了。目标组件只管从props里面拿来用就行了。

到这里位置,高阶组件就讲完了。你再返回去理解下定义,是否是豁然开朗~

你如今理解react-reduxconnect函数~

reduxstateaction建立函数,经过props注入给了Component
你在目标组件Component里面能够直接用this.props去调用redux stateaction建立函数了。

ConnectedComment = connect(mapStateToProps, mapDispatchToProps)(Component);

至关于这样

// connect是一个返回函数的函数(就是个高阶函数)
const enhance = connect(mapStateToProps, mapDispatchToProps);
// 返回的函数就是一个高阶组件,该高阶组件返回一个与Redux store
// 关联起来的新组件
const ConnectedComment = enhance(Component);

antd的Form也是同样的

const WrappedNormalLoginForm = Form.create()(NormalLoginForm);

参考地址:

  1. http://huziketang.com/books/r...

  2. https://react.bootcss.com/rea...

相关文章
相关标签/搜索