反应组件方法中为什么要绑定这
如果你尝试使用过<代码> 代码>反应进行前端开发,一定见过下面这样的代码:
<代码类=" language-jsx ">//假想定义一个ToggleButton开关组件 类ToggleButton延伸React.Component { 构造函数(道具){ 超级(道具); 这一点。状态={isToggleOn:真}; 这一点。handleClick=this.handleClick.bind(这个); 这一点。handleChange=this.handleChange.bind(这个); } handleClick () { 这一点。设置状态(prevState=比;({ isToggleOn: preveState.isToggleOn ! })); } handleChange () { console.log (this.state.isToggleOn); } 呈现(){ 回报( & lt;按钮>。handleClick=this.handleClick.bind(这);代码>
此时的<代码> 代码>指向新生成的实例,那么赋值语句右侧的表达式先查找<代码>。handleClick() 代码>这个方法,由对象的属性查找机制(沿原型链由近及远查找)可知此处会查找到<强>原型方法<代码>。handleClick() 代码> >强,接着执行<代码> bind()> 代码,此处的<代码> 代码>指向新生成的实例,所以赋值语句右侧的表达式计算完成后,会生成一个指定了<代码> 代码>的新方法,接着执行赋值操作,将新生成的函数赋值给实例的<代码> handleClick 代码>属性,由对象的赋值机制可知,此处的<代码> handleClick> 代码会直接作为实例属性生成。总结一下,上面的语句做了一件这样的事情:
<强>把原型方法<代码> handleClick() 代码>改变为实例方法<代码> handleClick()> 代码,并且强制指定这个方法中的<代码> 代码>指向当前的实例。强>
2。ES5的写法中为什么不用绑定(这)?
ES5的写法是指使用<代码>反应。createClass() 代码>方法来定义组件,<代码> 代码>反应在V16以上的新版本中已经移除了这个API,你可以通过阅读更早版本的源代码看到这个方法的细节。
<代码类=" language-js ">//旧版本“反应”中“createClass”方法片段 如果(this.__reactAutoBindMap) { this._bindAutoBindMethods (); }代码>
在老版本的<代码> 代码>中反应,<代码> createClass() 代码>的定义中可以看到上面的代码,抛开其他复杂的逻辑,从方法名就可以看出这是一个自动绑定的方法,实际上在这个方法中所完成的,就是对组件中自定义方法的<代码> 代码>强制绑定,感兴趣的读者可以自行翻看源码了解细节。
3。绑定这的必要性
在组件上绑定事件监听器,是为了响应用户的交互动作,特定的交互动作触发事件时,监听函数中往往都需要操作组件某个状态的值,进而对用户的点击行为提供响应反馈,对开发者来说,这个函数触发的时候,就需要能够拿到这个组件专属的状态合集(例如在上面的开关组件<代码> ToggleButton> 代码例子中,它的内部状态属性<代码> state.isToggleOn> 代码的值就标记了这个按钮应该显示在或者 ),所以此处强制绑定监听器函数的<代码> 代码>指向当前实例的也很容易理解。
反应构造方法中的绑定会将响应函数与这个组件组件进行绑定以确保在这个处理函数中使用这个时可以时刻指向这一组件的实例。
引用>4。如果不绑定这
如果类定义中没有绑定<代码> 代码>的指向,当用户的点击动作触发<代码>。handleClick() 代码>这个方法时,实际上执行的是<强>原型方法>强劲,可这样看起来并没有什么影响,如果当前组件的构造器中初始化了<代码> 代码>状态这个属性,那么原型方法执行时,<代码> this.state> 代码会直接获取实例的<代码> 代码>状态属性,如果构造其中没有初始化国家<代码> 代码>这个属性(比如中反应的UI组件),说明组件没有自身状态,此时即使调用原型方法似乎也没什么影响。
<强>事实上的确是这样,这里的<代码> bind() 代码>所希望提前规避的,就是著名的这个指针丢失的问题强>。
例如使用解构赋值的方式获取某个属性方法时,就会造成引用转换丢失这样的问题:
<代码类=" language-js "> const toggleButton=new toggleButton (); 进口{handleClick}=toggleButton; 代码>上例中解构赋值获取到的<代码> handleClick 代码>这个方法在执行时就会报错,类的内部是强制运行在严格模式下的,此处的<代码> 代码>在赋值中丢失了原有的指向,在运行时指向了<代码>定义>
反应组件方法中为什么要绑定