手机版

反应组件中绑定的示例代码

时间:2021-08-30 来源:互联网 编辑:宝哥软件园 浏览:

在React组件中处理类似onClick的事件绑定时,需要显式地将上下文绑定到处理器,这使得代码变得冗余和难看。

请参见以下示例:

类App扩展了Component { constructor(){ super();this . state={ ischeck d : false };} render(){ return(div class name=' App ' label check me : input type=' checkbox ' checking={ this . state . ischecked } onChange={ this . toggle check }//label/div);} toggleCheck(){ this . setstate(currentState={ return { ischeck d :currentstate . ischecked };});}}在页面上放置一个checkbox元素,并单击它以切换其选定状态。这是一段直观的代码,但它并没有您想象的那么好。

事件处理程序上下文丢失的错误报告

因为在checkbox的onChange事件处理程序中找不到React组件的setState方法,所以它表明其执行的上下文不是组件,而是其他东西。让我们具体调试一下。

调试以查看缺少上下文后的值

没想到,它是未定义的。这个方法是在完全没有任何上下文的环境中执行的。

为什么

当然,这不是React的锅,这是JavaScript的工作原理。详见第2:章这一切现在都有意义了!要追溯潜在的原因,简单来说,这个的值取决于如何调用函数。

默认绑定

函数display(){ console . log(this)} display()//在严格模式下是全局窗口,在非严格模式下是“未定义的”

隐式结合

通过隐式指定了函数上下文的对象调用。

var obj={ name: 'Nobody ',display : function(){ console . log(this . name);} };obj . display();//没人。它在obj上采用名称属性。但是如果这个对象上的方法被赋给其他变量或者以参数传递的形式执行,情况又会不一样。

var obj={ name: 'Nobody ',display : function(){ console . log(this . name);}};var name='global!';var outerDisplay=obj.displayoutdisplay();//全局!这里得到的‘name’是全局中的内部的,然后赋值给outerDisplay后调用相当于调用一个普通的函数,而不是对象中的函数,所以此时这是一个全局对象,在全局中只定义了一个name变量。同样,在严格模式下,因为此时未定义,所以无法访问所谓的undefiend.name,因此将引发错误。

函数调用程序(fn){ fn();}setTimeout(obj.display,1000);//全局!invoker(obj . display);//全局!这里调用setTimeout的时候,因为它的签名实际上是setTimeout(fn,delay),可以理解为obj.display被赋给了它的输入参数fn,它实际上执行的是fn,而不是对象上的方法。调用者函数也是如此。

强制绑定

这时,bind成了拯救世界的英雄,我们可以随时明确指定函数的执行上下文。

var name="全局!";obj . display=obj . display . bind(obj);var outerDisplay=obj.displayoutdisplay();//Nobodybind将指定的上下文绑定到函数,并返回一个新函数。如果这个新函数被赋值或传递参数,它将不会影响它的上下文,并且它将始终是我们在执行它时指定的那个。

场地缩减

有了以上背景,我们就可以还原文章开头的问题,即事件处理程序上下文的丢失。

JSX的HTML标签本质上对应于React中创建标签的一个函数。例如,您编写的div编译会议实际上是React.createElement('div ')。所以当你写输入时,你实际上调用React.createElement来创建一个输入标签。

react.createElement上的属性(类型,[道具],[.children])标记作为道具参数传递给createelement函数。

Inputonchange={ this。toggleCheck}意味着组件中的toggleCheck方法被分配给createElement的参数props(props是一个接收标签上写的所有属性的对象,)。如上所述,当实际调用时,组件中的togglecheck方法不再被调用。

做出反应。createelement (type,props){//让我们创建一个类型并调用` props。onchange `.道具。onchange()//不再是原来的方法,上下文丢失.}因为ES6 Class是在严格模式下执行的,如果在事件处理程序中使用了这一点,则是未定义的。

因此,在React的正式示例中,您在构造函数中看到语句bind(this)并不奇怪,这只是为了纠正该事件处理程序扭曲的执行上下文。

构造函数(){ super();this . state={ ischeck d : false };this . toggle check=this . toggle check . bind(this);}

这很正常,但是这段代码的存在确实很尴尬,因为,

对于业务来说,毫无意义,增加代码量也很难看。每个处理器都添加了这样的绑定冗余,使得项目中重复的代码是冗余的,在搜索中混淆了原来的方法

有很多方法可以避免它,这取决于哪一种味道最好。让我们看看如何避免编写这些绑定方法。

#0行内的绑定

在最简单的情况下,绑定操作可以在行中执行,这样就不需要写一句话。

输入类型=“复选框”已选中={this。state . ischecked }-onchange={ this。togglecheck} onchange={this。togglecheck.bind (this)}/# 1箭头函数

因为arrow函数没有创建新的作用域,所以它的上下文是语义上的。因此,在绑定事件处理程序时,直接使用裁剪函数非常方便。

输入类型='checkbox '选中={ this . state . ischecked }-onChange={ this . toggle check } onChange={()=this . toggle check()}/

#2将类的方法改为属性

如果把这个处理器看作这个组件的一个属性,那么这个属性就是以箭头函数的形式作为一个事件处理器存在的,执行时可以正常获取上下文。

-toggle check(){ toggle check=()={ this . setstate(currentState={ return { ischeck d :currentstate . ischecked };});}摘要

在React组件中,其实和React关系不大。当将事件处理程序或方法作为回调传递时,其上下文将丢失。要修复它,我们需要显式地将上下文绑定到这个方法。除了在构造函数中常用之外,通过箭头函数和公共属性可以避免冗余的绑定语句。

版权声明:反应组件中绑定的示例代码是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。