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

(上一篇已经说过了高阶组件可以用来解决交叉问题)

一、不要改变原始组件,使用组合

class A extends React.PureComponent{
constructor(props){
super(props);
this.state={
content:"我是A"
}
}
componentWillReceiveProps(nextProps){
this.setState({
content:nextProps.content
})
}
componentDidMount(){
console.log("a挂载完毕")
}
render(){
return(
<p>{this.state.content}</p>
)
}
} class B extends React.PureComponent{
constructor(props){
super(props)
this.state={
content:'我是B'
}
}
componentDidMount(){
console.log("b挂载完毕")
}
render(){
return(
<button style={{color:'red'}}>{this.state.content}</button>
)
}
} function initContent(Aa){
// Aa.prototype.componentDidMount=function(){
// console.log("我先挂载好的")
// }
return class K extends React.Component{
constructor(props){
super(props);
this.state={
content:"我是高阶组件生成的"
}
}
componentDidMount(){
this.setState({
content:"我现在为C"
})
console.log("c挂载完毕")
}
render(){
return(
<Aa content={this.state.content} />
)
}
}
} const A1 = initContent(A);
const B1 = initContent(B)
ReactDOM.render(<div><B1></B1><A1></A1></div>, document.getElementById("root"));

若放开上面代码中的注释,那么包裹组件该方法原有的逻辑将被重写,可能会引起冲突。

二、约定:将不相关的props属性传递给包裹组件

render() {
// 过滤掉与高阶函数功能相关的props属性,
// 不再传递
const { extraProp, ...passThroughProps } = this.props; // 向包裹组件注入props属性,一般都是高阶组件的state状态
// 或实例方法
const injectedProp = someStateOrInstanceMethod; // 向包裹组件传递props属性
return (
<WrappedComponent
injectedProp={injectedProp}
{...passThroughProps}
/>
);
}

三、约定:最大使用组合

const ConnectedComment = connect(commentSelector, commentActions)(Comment);

等于下面

// connect是一个返回函数的函数(译者注:就是个高阶函数)
const enhance = connect(commentListSelector, commentListActions);
// 返回的函数就是一个高阶组件,该高阶组件返回一个与Redux store
// 关联起来的新组件
const ConnectedComment = enhance(CommentList);

这个有点类似于jq中的链式调用

四、约定:包装显示名字以便于调试

注意事项

一、不在render函数中使用高阶组件

简单来说react使用差异算法,当再render中使用高阶组件时,每次render返回的高阶组件都是新创建的,与原来的一定不一致,所以每次都要重新渲染,

这里产生的问题不仅仅是性能问题 —— 还有,重新加载一个组件会引起原有组件的所有状态和子组件丢失。

二、必须将静态方法做拷贝

这里我只介绍一个方法

function enhance(WrappedComponent) {
class Enhance extends React.Component {/*...*/}
// 必须得知道要拷贝的方法 :(
Enhance.staticMethod = WrappedComponent.staticMethod;
return Enhance;
}

三、refs属性不能传递

参考:https://doc.react-china.org/docs/higher-order-components.html

学习React系列(九)——高阶函数的更多相关文章

  1. javascript设计模式学习之三—闭包和高阶函数

    一.闭包 闭包某种程度上就是函数的内部函数,可以引用外部函数的局部变量.当外部函数退出后,如果内部函数依旧能被访问到,那么内部函数所引用的外部函数的局部变量就也没有消失,该局部变量的生存周期就被延续. ...

  2. python学习-41 装饰器 -- 高阶函数

    装饰器:本质就是函数.是为其他函数添加附加功能的. 原则:1.不修改被修饰函数的源代码2.不修改被修饰函数的调用方式 --- 装饰器的知识储备 装饰器=高阶函数+函数嵌套+闭包 高阶函数 1.高阶函数 ...

  3. kotlin学习(7)高阶函数

    高阶函数 以另一个函数作为参数或者返回值的函数被称为高阶函数. 函数类型 //隐式声明(省略了变量类型) val sum = (x:Int, y:Int -> x+y) val action = ...

  4. 廖老师JavaScript教程高阶函数-sort用法

    先来学习一个新词:高阶函数 高阶函数英文叫Higher-order function.那么什么是高阶函数? JavaScript的函数其实都指向某个变量.既然变量可以指向函数,函数的参数能接收变量,那 ...

  5. kotlin高阶函数实战&DSL入门

    传统函数演示: 这里以电视节目“非诚勿扰”为例,男人去从一大堆美女当中挑选出自己中意的对象,比如台上有24位妹子,其档案如下: 接下来第一个男嘉宾出场啦,如下: 下面用代码来实现一下,比较简单: 先定 ...

  6. Python学习笔记系列——高阶函数(map/reduce)

    一.map #变量可以指向函数,函数的参数能接受变量,那么一个函数就可以接受另一个函数作为参数,这种函数被称之为高阶函数 def add(x,y,f): return f(x)+f(y) print( ...

  7. python函数式编程之高阶函数学习

    基本概念 函数式编程,是一种抽象程度很高的编程范式,纯粹的函数式编程语言编写的函数没有变量.因此,任意一个函数,只要输入确定,输出就确定的这种函数我们称之为纯函数,我们称这种函数没有副作用.而允许使用 ...

  8. JavaScript学习笔记(十)——高阶函数之map,reduce,filter,sort

    在学习廖雪峰前辈的JavaScript教程中,遇到了一些需要注意的点,因此作为学习笔记列出来,提醒自己注意! 如果大家有需要,欢迎访问前辈的博客https://www.liaoxuefeng.com/ ...

  9. 深入理解javascript函数进阶系列第一篇——高阶函数

    前面的话 前面的函数系列中介绍了函数的基础用法.从本文开始,将介绍javascript函数进阶系列,本文将详细介绍高阶函数 定义 高阶函数(higher-order function)指操作函数的函数 ...

随机推荐

  1. WPF 16进制byte输入框

    在WPF中,针对byte类型的输入控件可以选用 XCEED 的免费库中的 Xceed.Wpf.Toolkit.ByteUpDown(可从nuget获取). 若要使该控件在界面上以16进制显示byte, ...

  2. poj-2909-哥德巴赫猜想

    Description For any even number n greater than or equal to 4, there exists at least one pair of prim ...

  3. 大数据 --> MapReduce原理与设计思想

    MapReduce原理与设计思想 简单解释 MapReduce 算法 一个有趣的例子:你想数出一摞牌中有多少张黑桃.直观方式是一张一张检查并且数出有多少张是黑桃? MapReduce方法则是: 给在座 ...

  4. Python第二话 初识复杂数据类型(list、dictionary、tuple)

    上一篇我们简单认识了数据类型:数字number和字符串string,这篇我们就来隆重介绍一下重量级的数据类型:列表list.字典dictionary和元组tuple. 一.列表List: ①列表是什么 ...

  5. 为什么说android UI操作不是线程安全的

    转载于:http://blog.csdn.net/lvxiangan/article/details/17218409#t2 UI线程及Android的单线程模型原则 使用Worker线程 Commu ...

  6. python全栈学习--day4

    列表 说明:列表是python中的基础数据类型之一,它是以[]括起来,每个元素以逗号隔开,而且他里面可以存放各种数据类型比如:   1 li = ['alex',123,Ture,(1,2,3,'wu ...

  7. SpagoBi开发示例——员工离职人数统计

    1.开发工具:SpagoBIStudio_5.1,操作界面和使用方法和eclipse没差 安装参考:http://www.cnblogs.com/starlet/p/4778334.html   2. ...

  8. 网络1712--c语言一二维数组作业总结

    1.成绩摆前头 1.1基本要求(1分) 按时交 - 有分 未交 - 0分 迟交一周以上 - 倒扣本次作业分数 抄袭 - 0分 泛泛而谈(最多七分) 1.2评分要点 PTA作业总结(4分) 同学代码互评 ...

  9. C语言博客作业—嵌套循环

    一.PTA实验作业 题目1:7-4 换硬币 1. 本题PTA提交列表 2. 设计思路 (1)定义整型变量money表示待换的零钱总额,p5表示5分硬币的数量,p2表示2分硬币的数量,p1表示1分硬币的 ...

  10. 冲刺NO.1

    Alpha冲刺第一天 站立式会议 项目进展 项目的第一天,主要工作是对项目的开发进行规划,以及将规划的成果转化为燃尽图与博客文章.依据项目需求分析报告与开题报告中已经完成的设计任务和项目规划,我们将系 ...