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

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

函数模拟高阶组件

  1. 最普通的方法,一个welcome,一个goodbye。两个函数先从localStorage读取了username,然后对username做了一些处理。
function welcome() {
let username = localStorage.getItem('username');
console.log('welcome ' + username);
} function goodbey() {
let username = localStorage.getItem('username');
console.log('goodbey ' + username);
} welcome();
goodbey();

我们发现两个函数有一句代码是一样的,这叫冗余。

我们要写一个中间函数,读取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();
goodbey();

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

我们增加个用户study函数。

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);

通俗理解 React 高阶函数的更多相关文章

  1. 用一个简单的例子来理解python高阶函数

    ============================ 用一个简单的例子来理解python高阶函数 ============================ 最近在用mailx发送邮件, 写法大致如 ...

  2. react高阶函数组件

    Layout as a Higher Order Component // components/MyLayout.js import Header from './Header'; const la ...

  3. react高阶组件的理解

    [高阶组件和函数式编程] function hello() { console.log('hello jason'); } function WrapperHello(fn) { return fun ...

  4. 函数式编程与React高阶组件

    相信不少看过一些框架或者是类库的人都有印象,一个函数叫什么creator或者是什么什么createToFuntion,总是接收一个函数,来返回另一个函数.这是一个高阶函数,它可以接收函数可以当参数,也 ...

  5. 学习React系列(九)——高阶函数

    定义:高阶组件就是一个函数,且该函数接收一个组件作为参数,并返回一个新的组件. (上一篇已经说过了高阶组件可以用来解决交叉问题) 一.不要改变原始组件,使用组合 class A extends Rea ...

  6. 理解运用JS的闭包、高阶函数、柯里化

    JS的闭包,是一个谈论得比较多的话题了,不过细细想来,有些人还是理不清闭包的概念定义以及相关的特性. 这里就整理一些,做个总结. 一.闭包 1. 闭包的概念 闭包与执行上下文.环境.作用域息息相关 执 ...

  7. JS高阶函数的理解(函数作为参数传递)

    JS高阶函数的理解 高阶函数是指至少满足下列条件之一的函数. · 函数可以作为参数被传递 · 函数可以作为返回值输出 一个例子,我们想在页面中创建100个div节点,这是一种写法.我们发现并不是所有用 ...

  8. Python之高阶函数如何理解?

    我们先要了解一下什么是所谓的高阶函数: 看定义:什么是高阶函数? 高阶函数:我们知道一个函数可以作为参数传给另外一个函数,或者一个函数的返回值为另外一个函数(若返回值为该函数本身,则为递归),如果满足 ...

  9. React.js高阶函数的定义与使用

    /* 高阶函数的简单定义与使用 一: 先定义一个普通组件 二: 用function higherOrder(WrappendComponent) { return } 将组件包裹起来,并用export ...

随机推荐

  1. 网页布局的应用(float或absolute)

    一个浮动(左浮动或右浮动) 垂直环绕布局(float.clear) 左右两列布局(float.absolute) 三栏网页宽度自适应布局(float.absolute) 注意:网页设计中应该尽量避免使 ...

  2. Android Weekly Notes Issue #318

    Android Weekly Issue #318 July 15th, 2018 Android Weekly Issue #318 本期内容包括: Android Navigation Compo ...

  3. Android Weekly Notes Issue #276

    September 24th, 2017 Android Weekly Issue #276 本期内容包括LifeCycle与Architecture的相关文章,以及新的JSON解析库Moshi的介绍 ...

  4. vuex原理笔记

    本文总结自: https://tech.meituan.com/vuex-code-analysis.html, 将要点提炼为笔记,以便不时之需,安不忘危. 核心可分为两部分: 1.vue.use(V ...

  5. g2o的一般过程

    1.自己定义顶点类.边类或者用已经有的.1.1定义顶点例子class CurveFittingVertex: public g2o::BaseVertex<3, Eigen::Vector3d& ...

  6. MySQL性能优化/调优:默认配置的修改

    在这里罗列一下这些配置, 每次新装MySQL的时候, 最好根据实际需要调整一下这些配置: max_connections 最大并发连接数.当MySQL的并发连接达到这个设定值时,新的连接将会被拒绝.当 ...

  7. 在你的网站中使用 AdSense广告

    下面介绍了如何使用Google的AdSense来为你的网站设置广告.基本内容包括: 创建一个AdSense账号,你必须18岁以上,有一个Google账号以及地址 你的网站必须已经被激活,并且你的网站内 ...

  8. 洛谷 2585 [ZJOI2006]三色二叉树——树形dp

    题目:https://www.luogu.org/problemnew/show/P2585 可以把不是绿色的记成一种.仔细一想不会有冲突.如果自己是绿色,孩子的不同颜色不会冲突:如果自己不是绿色,自 ...

  9. Words Gems

    所有的东西都来自抄袭.来自学习.不同的是用新的方法做其他公司做过的事情.很多公司做同样的事情,但只有一家公司最成功.你要发现一个有需求的服务,并做得比别人更好,而不是比别人更早.

  10. Spring boot 学习 九

    一:经过试验发现,如果使用如下的Controller(@RequestBody), 前台POST的请求body只能是JSON,如果是form-data, X-www-form-urlencoded 或 ...