助你完全理解React高阶组件(Higher-Order Components)

前端之家收集整理的这篇文章主要介绍了助你完全理解React高阶组件(Higher-Order Components)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

助你完全理解React高阶组件(Higher-Order Components)

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

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

高阶组件定义

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

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

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

函数模拟高阶组件

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

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

  1. function welcome() {
  2. let username = localStorage.getItem('username');
  3. console.log('welcome ' + username);
  4. }
  5.  
  6. function goodbey() {
  7. let username = localStorage.getItem('username');
  8. console.log('goodbey ' + username);
  9. }
  10.  
  11. welcome();
  12. goodbey();
  1. 我们发现两个函数有一句代码是一样的,这叫冗余唉。不好不好~(你可以把那一句代码理解成平时的一大堆代码

    1. 我们要写一个中间函数,读取`username`,他来负责把`username`传递给两个函数
  1. function welcome(username) {
  2. console.log('welcome ' + username);
  3. }
  4.  
  5. function goodbey(username) {
  6. console.log('goodbey ' + username);
  7. }
  8.  
  9. function wrapWithUsername(wrappedFunc) {
  10. let newFunc = () => {
  11. let username = localStorage.getItem('username');
  12. wrappedFunc(username);
  13. };
  14. return newFunc;
  15. }
  16.  
  17. welcome = wrapWithUsername(welcome);
  18. goodbey = wrapWithUsername(goodbey);
  19.  
  20. welcome();
  21. welcome();

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

我们增加用户study函数

  1. function study(username){
  2. console.log(username+' study');
  3. }
  4. study = wrapWithUsername(study);
  5.  
  6. study();

这里你是不是理解了为什么说wrapWithUsername是高阶函数?我们只需要知道,用wrapWithUsername包装我们的study函数后,study函数第一个参数是username

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

高阶组件

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

我们把上一节的函数统统改成react组件。

  1. 最普通的组件哦。

welcome函数转为react组件。

  1. import React,{Component} from 'react'
  2.  
  3. class Welcome extends Component {
  4. constructor(props) {
  5. super(props);
  6. this.state = {
  7. username: ''
  8. }
  9. }
  10.  
  11. componentWillMount() {
  12. let username = localStorage.getItem('username');
  13. this.setState({
  14. username: username
  15. })
  16. }
  17.  
  18. render() {
  19. return (
  20. <div>welcome {this.state.username}</div>
  21. )
  22. }
  23. }
  24.  
  25. export default Welcome;

goodbey函数转为react组件。

  1. import React,{Component} from 'react'
  2.  
  3. class Goodbye extends Component {
  4. constructor(props) {
  5. super(props);
  6. this.state = {
  7. username: ''
  8. }
  9. }
  10.  
  11. componentWillMount() {
  12. let username = localStorage.getItem('username');
  13. this.setState({
  14. username: username
  15. })
  16. }
  17.  
  18. render() {
  19. return (
  20. <div>goodbye {this.state.username}</div>
  21. )
  22. }
  23. }
  24.  
  25. export default Goodbye;
  1. 现在你是不是更能看到问题所在了?两个组件大部分代码都是重复的唉。

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

  1. import React,{Component} from 'react'
  2.  
  3. export default (WrappedComponent) => {
  4. class NewComponent extends Component {
  5. constructor() {
  6. super();
  7. this.state = {
  8. username: ''
  9. }
  10. }
  11.  
  12. componentWillMount() {
  13. let username = localStorage.getItem('username');
  14. this.setState({
  15. username: username
  16. })
  17. }
  18.  
  19. render() {
  20. return <WrappedComponent username={this.state.username}/>
  21. }
  22. }
  23.  
  24. return NewComponent
  25. }

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

  1. import React,{Component} from 'react';
  2. import wrapWithUsername from 'wrapWithUsername';
  3.  
  4. class Welcome extends Component {
  5.  
  6. render() {
  7. return (
  8. <div>welcome {this.props.username}</div>
  9. )
  10. }
  11. }
  12.  
  13. Welcome = wrapWithUsername(Welcome);
  14.  
  15. export default Welcome;
  1. import React,{Component} from 'react';
  2. import wrapWithUsername from 'wrapWithUsername';
  3.  
  4. class Goodbye extends Component {
  5.  
  6. render() {
  7. return (
  8. <div>goodbye {this.props.username}</div>
  9. )
  10. }
  11. }
  12.  
  13. Goodbye = wrapWithUsername(Goodbye);
  14.  
  15. export default Goodbye;

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

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

你现在理解react-reduxconnect函数~

reduxstateaction创建函数,通过props注入给了Component
你在目标组件Component里面可以直接用this.props调用redux stateaction创建函数了。

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

相当于这样

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

antd的Form也是一样的

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

参考地址:

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

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

猜你在找的React相关文章