官方定义: is a helper to bind a list of methods to an object referencecss
理解: 由于不推荐在render()里构建函数,做者就用了6行代码封装了函数绑定事件的代码.
bindme的npm包实际上由6行ES5代码组成,可是确实方便了不少.这个包值得一用react
有时候咱们并不会直接在建立事件的时候bind
,而是统一在constructor上绑定事件,若是一个模块大起来,就会出现好几十行绑定事件的代码,用bindme
能够很好解决.例如面试
//原写法 this.clickEvent1 = this.clickEvent1.bind(this) this.clickEvent2 = this.clickEvent2.bind(this) this.clickEvent3 = this.clickEvent3.bind(this) this.clickEvent4 = this.clickEvent4.bind(this) this.clickEvent5 = this.clickEvent5.bind(this) //bindme写法 bindme(this, 'clickEvent1', 'clickEvent2', 'clickEvent3', 'clickEvent4', 'clickEvent5')
又好看又方便npm
也能够在super
构建实例的时候绑定函数
bindme(super(props), 'clickEvent1', 'clickEvent2', 'clickEvent3', 'clickEvent4', 'clickEvent5', )
就是这么简单的用法, 咱们能够看看它的源码转换成ES6是怎么样的性能
const bindme = (self, ...funcs) => { funcs.forEach(func => { if (self[func]) { self[func] = self[func].bind(self) } else { console.error(`Method ${func} is not defined`) } }) }
其实也就是收集全部的事件,再统一bind,若是不存在的抛出异常.咱们在平时也会常常封装一些相似这些小的便捷操做this
import React,{ PureComponent } from 'react' import bindme from 'bindme' import './style.css' export default class BindmeComp extends PureComponent{ constructor(props){ bindme(super(props), 'bindmeOnMouseOver' ) this.initClickMode = this.initClickMode.bind(this) bindme(this, 'bindmeFirClickMode', 'bindmeSecClickMode') } noThisClickMode(){ console.log('未绑定this事件 =========>', this) } initClickMode(){ console.log('普通bind事件 ===========>', this) } arrowClickMode = () => { console.log('箭头函数bind事件 ===========>', this) } bindmeFirClickMode(){ console.log('bindme事件1 ===========>', this) } bindmeSecClickMode(){ console.log('bindme事件2 ===========>', this) } bindmeOnMouseOver(){ console.log('bindme事件3 ===========>', this) } render(){ return( <div> <div className="list"> <span>未绑定this事件</span> <button onClick={ this.noThisClickMode }>点击</button> </div> <div className="list"> <span>普通bind事件</span> <button onClick={ this.initClickMode }>点击</button> </div> <div className="list"> <span>箭头函数事件</span> <button onClick={ this.arrowClickMode}>点击</button> </div> <div className="list"> <span>bindme</span> <button onClick={ this.bindmeFirClickMode }>点击</button> </div> <div className="list"> <span>bindme2</span> <button onClick={ this.bindmeSecClickMode } >点击</button> </div> <div className="list"> <span>bindme3</span> <button onMouseOver={ this.bindmeOnMouseOver } >滑过</button> </div> </div> ) } }
上面基本覆盖了经常使用的事件绑定状况.咱们看看都会输出什么?spa
能够看到,除了第一个this为undefined外,其余都是正常绑定在了组件上code
咱们先从咱们最熟悉js的this
提及;对象
面试官常常会问,什么是this?this指向什么?
通常来讲:
谁调用该function
,该函数的this就指向这个调用方
有一个特殊的状况,ES6的箭头函数,也是面试官特别喜欢的一个东西(但它确实好用),因为箭头函数不存在this,因此它的this是由上一层继承而来的.因此能够得出结论箭头函数的this始终指向构造时的对象,而不是使用时的对象
另外箭头函数还有一些不一样于普通函数的特性,好比: 不能够看成构造函数使用,即不能够new
. 不可使用arguments
属性等等
总结一句话就是:
普通函数this是动态的,而箭头函数的this是静态的
由于React组件是经过class
构造的,因此组件里的全部属性,全部方法均可以经过this来获取,例如咱们常用的属性state.就能够经过this.state.xxx
获取
因此咱们只须要保证this永远指向该构造对象(组件)便可,因此咱们通常不会经过function来建立函数(会使得this动态指向调用function的对象), 而且:
React组件类的方法没有默认绑定this到组件实例,须要手动绑定。
因此就衍生出了绑定this的方法;经常使用的有四种,咱们通常会使用在constructor里面bind
//优先级最高 constructor(props){ super(props); this.handleEvent = this.handleEvent.bind(this) }
这种和直接在构建事件中绑定很像对吧?
<input onChange={this.handleEvent.bind(this)} />
原理虽然是同样的,可是性能却差了一大截.为何?
咱们知道只要state
值改变了,就会致使render从新渲染,若是直接在建立事件绑定,那每一次渲染的时候都须要从新绑定一次,会大大下降性能.相反,只要在构造的时候绑定,不管渲染多少次,绑定都仍是一次
此外还有比较经常使用的箭头函数绑定法和::
绑定法
前面也介绍了箭头函数this的知识,因此在React出现也是蛮高的
handleEvent = () => { ... } <input onChange={this.handleEvent} />
::
虽然也能够绑定this,可是由于不能传参数,因此不常用
handleEvent = () => { ... } <input onChange={::this.handleEvent} />