原文地址: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
最普通的方法,一个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();
咱们发现两个函数有一句代码是同样的,这叫冗余唉。很差很差~(你能够把那一句代码理解成平时的一大堆代码)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
组件。
最普通的组件哦。
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;
如今你是否是更能看到问题所在了?两个组件大部分代码都是重复的唉。
按照上一节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-redux
的connect
函数~
把redux
的state
和action
建立函数,经过props
注入给了Component
。
你在目标组件Component
里面能够直接用this.props
去调用redux state
和action
建立函数了。
ConnectedComment = connect(mapStateToProps, mapDispatchToProps)(Component);
至关于这样
// connect是一个返回函数的函数(就是个高阶函数) const enhance = connect(mapStateToProps, mapDispatchToProps); // 返回的函数就是一个高阶组件,该高阶组件返回一个与Redux store // 关联起来的新组件 const ConnectedComment = enhance(Component);
antd
的Form也是同样的
const WrappedNormalLoginForm = Form.create()(NormalLoginForm);
参考地址: