react之bind函数到组件通识篇
前言
在说起react的函数绑定之前,我们有必要了解下bind函数的作用是什么,函数的执行的上下文以及其默认的this是指向的哪里?有点抽象?那么你可以去看下下面的两个方法的执行会有什么区别吧。
let customer={name:'Robin',getName:function(){console.log(this.name);} } customer.getName();//Robin let getName = customer.getName; getName();// CodePen let getNameWithCustomer = customer.getName.bind(customer); getNameWithCustomer();// Robin 复制代码如果你猜不出结果,可以看下我的codePen链接:链接,这是为什么呢?这是因为上下文不同,也就是this不同,当你通过赋值拿到方法,方法执行时会先去查看其上下文的this是什么,而不是直接使用其来源于哪个对象的。那么如果我们想使用对象里的属性,可以使用bind方法绑定一个指定的对象。于是我们又得到了我们期望的name:robin值。
从上面的结果中,我们得到了以下的几个认知:
1 函数调用时,只取决于其实际执行环境,与来源无关
2 如果我们希望函数执行或者函数拷贝时,不丢失参数,或者避免参数错误,我们应该将参数传入,而不要过度依赖当前this的上下文。
3 如果我们只是一个工具函数,那么你可能没有特别的场景一定要绑定什么,比如你定义一个add方法计算两个参数的和,那么你不需要绑定其他的对象或者上下文。
4 如果我们希望函数执行时,在某个环境或者类内绑定指定的上下文,那么你需要显性的绑定this才可以使用这个对象里的属性以及属性方法。
5 如果我们喜欢函数执行时,希望可以根据需求绑定任意的对象,也建议函数定义时,考虑好这一点,并绑定时绑定其对应的对象,这时候很可能你绑定的不是"this"。
6 bind方法只是改变上下文,并不会导致函数的执行。
备注:更多关于this的文章,详解请看我另外两篇文章,有非常详尽的说明:神奇的this:链接, js中的作用域:链接
react中的事件绑定
react中的事件绑定,我们按照无参和有参两种。无参非常简单,直接绑定函数即可。当我们需要传递参数时,刚入门前端的人可能会直接绑定参数。这样会导致两个错误,1 丢失了事件参数 2 导致了函数的直接执行,而不是点击后执行。(作为常识,我们还要知道,默认的点击事件等事件是会返回event对象的哦)。
备注:如果你不清楚前端的事件流机制,可以查看我的js中事件流机制:链接
handleClick(e){ const {type} = e;// click} render(){const text = 'button text';return (<button onClick={this.handleClick}></button>)} // 直接传参会导致错误 render(){const text = 'button text';return (<button onClick={this.handleClick(text)}></button>)}// 通过箭头函数 避免这种问题 render(){const text = 'button text';return (<button onClick={(e,text) => this.handleClick(e,text)}></button>)} 复制代码所以你通过箭头函数避免了上面的错误,但这种使用与我们的常规使用是不同的。为什么呢?因为我们一般在react组件中需要经常使用当前组件的上下文,包括当前组件的state、方法以及传入的属性等。这时候,我们想起了前言中的bind语法,其可以改变上下文的this,支持事件获知的同时,绑定当前对象。而且我们通过bind的语法清楚,其不但可以绑定上下文,还可以支持灵活的传参,如果你不清楚其基本语法,可以查看js- MDN的介绍:链接.
下面的内容借鉴于react中文官网的教程--传递函数给组件,做了简单的整理:原文链接:链接,有以下的几种方式。
// 第一种 :render 中bind绑定 render(){const text = 'button text';return (<button onClick={ this.handleClick.bind(this,text)}></button>) } // 第二种 :constructor bind绑定 constructor(props){this.handleClick = this.handleClick.bind(this); } render(){const text = 'button text';return (<button onClick={ (e,text)=> this.handleClick(e,text)}></button>) }// 第三种 :class func 箭头函数 <=> 上面的调用方法均是常规方法写法 handleClick=()=>{} render(){const text = 'button text';return (<button onClick={(e,text)=> this.handleClick(e,text)}></button>) } 复制代码需要注意的是,在官网文档中,我们看到在rende函数中使用箭头函数以及使用bind绑定都会影响性能,而在constructor中将所有函数绑定一遍又过于繁琐,我们一般的框架中习惯于使用class 属性函数,--箭头函数的方式实现,也就是上面代码中的第三种,同样,我们在react ant的ui框架的input组件中找到了icon的元素事件传递的方式也是第三种,查看链接。参考下面的原代码:
handleReset = (e: React.MouseEvent<HTMLElement, MouseEvent>) => {this.setValue('', e, () => {this.focus();});};renderClearIcon(prefixCls: string) {const { allowClear } = this.props;const { value } = this.state;if (!allowClear || value === undefined || value === null || value === '') {return null;}return (<Icontype="close-circle"theme="filled"onClick={this.handleReset}className={`${prefixCls}-clear-icon`}role="button"/>);} 复制代码小结
通过本文希望你能清楚我们为什么要bind this,以及如何正确绑定的一些可行方式,和每种方式的优缺点,还有一些如何避免低级错误,导致函数直接执行的原因。同样,我们也知道了一般的ui框架中采用的是哪种方式--类属性的方式。
更多精彩内容跳转:原文语雀连接
寄语
我们一起从从小白到大师。 --- Robin
转载于:https://juejin.im/post/5ca81acce51d452e62014939
总结
以上是生活随笔为你收集整理的react之bind函数到组件通识篇的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: C#8.0可空引用类型的使用注意要点
- 下一篇: 优化出现的小问题