本文主要记录如何使用高阶组件实现外部逻辑注入,如性能打点,以及其中遇到的一些问题
所谓高级组件,即:接受一个组件作为参数,并且其返回值也为一个react组件
如下是一个再简单不过的react组件
import connect from './connect' import {Component} from 'react' class Demo extends Component { componentWillMount(){ //do something here } render(){ return <div>111</div> } } export default connect(Demo)connect 是一个实现性能打点的装饰器,here is the source code
装饰器,在本质上,其实是返回一个函数的高阶函数。在react应用中,衍生出了高阶组件的含义
以下是两种HOC的实现方式:
connect 装饰器可以实现保持原有方法componentWillMount和componentDidMount纯净的情况下,实现打点逻辑的无污染注入。经过装饰以后的组件,就可以在控制台打印出该组件的渲染时间。
你可以看到,返回的 HOC 类(Enhancer)继承了 Target。之所以被称为 Inheritance Inversion 是因为 Target被Enhancer继承了,而不是Target继承了Enhancer。在这种方式中,它们的关系看上去被反转(inverse)了。
Inheritance Inversion 允许 HOC 通过this 访问到 Target,意味着它可以访问到 state、props、组件生命周期方法和 render方法。
遗留问题
如何去手动connect,对项目中定义的所有react组件实现自动逻辑注入(talentLibs库的实现方式是什么样的?)
这里主要记录在写demo的过程中,遇到的几个问题:
在给类定义方法时,如果使用了箭头函数,发现在prototype上访问不到该方法,主要原因如下: what happens when using arrow function to define method on class
//deom1 class Super{ sayName(){ //do some thing here } } //通过Super.prototype可以访问到sayName方法,这种形式定义的方法,都是定义在prototype上 var a = new Super() var b = new Super() a.sayName === b.sayName //true //所有实例化之后的对象共享prototypy上的sayName方法 //demo2 class Super{ sayName =()=>{ //do some thing here } } //通过Super.prototype访问不到sayName方法,该方法没有定义在prototype上 var a = new Super() var b = new Super() a.sayName === b.sayName //false //实例化之后的对象各自拥有自己的sayName方法,比demo1需要更多的内存空间通过demo1这种方式,我们可以在Super.prototype上访问到sayName方法
但是通过使用demo2的定义方式,我们在Super.prototype上访问不到sayName方法
if you use the reserved key word class in ES6 to declare a class like demo1,the method will be defined on the prototype.However,when using arrow function,the method will be bound with this.
在定义一个类时,如果使用demo1中的方式给类添加方法,那么这个方法将被定义在类的prototype上。然而如果使用箭头函数的话,这个方法将会被定义在this上,即Super的实例化之后的对象。而且在这个方法内,this始终会指向这个对象,而不管方法的调用方式(箭头函数的特性)
深入了解HOC
