React判断一个元素是否是HTML元素还是React组件元素的原则就是看第一个字母是否大写,如果是大写的话那么就会按照JSX的处理方式来解析这个元素;如果是小写的话,那么就会被认为是一个HTML原生元素,所以不需要对其进行什么转译操作。正是由于两者的处理方式不同,所以我们需要切记:React元素的名字必须大写开头;HTML元素必须以小写开头。
1.为什么需要给事件处理函数显式的绑定环境对象
我们在react组件中经常会遇见某些非原生的事件处理函数会需要将它的环境对象绑定到我们的React组件元素上,这里解答两个疑问。疑问1:为什么这些非原生的事件处理函数需要将其环境对象绑定到React实例化的组件元素上呢?首先,并不是所有的事件处理函数都需要将其环境对象绑定到React实例化的组件元素上,在下面那些情况下是必须的,那就是当我们的事件处理函数内部具有处理这个React实例组件操作的逻辑时才需要将其环境对象硬绑定为React实例组件。
疑问2:为什么这个事件处理函数的执行环境不是指向React实例化的组件?要知道我们定义的处理函数所处的位置是在React组件构造类的内部呀,,但是这又能怎么样呢。。通过之前的学习环境对象学习我们就知道,一个普通函数(箭头函数除外)的环境对象指向谁并不由函数定义的位置决定,而是由函数被调用的位置所决定。那么问题来了,我们定义的事件处理函数是在哪里被调用的呢?被谁所调用呢?由于事件处理函数是作为参数传入事件监听器里面的,所以我觉得事件处理函数的调用方式就是普通调用。对于一个普通调用函数,他的环境对象总是指向window。经过例子验证后,发现情况并不是这样的,在我验证的这种情况下,事件处理函数的环境对象指着null。总之,无论如何事件处理函数的环境对象并不一定指向React构造函数实例化出来的那个对象。下面看一看那个验证代码:
class T0607_0 extends Component{
constructor(props){
super(props)
}
clickHander(event){
alert(Object.prototype.toString.call(this))//[object Null]
alert(event.target)//[object HTMLButtonElement]
}
render(){
return (
<div><button onClick = {this.clickHander}>click</button></div>
)
}
}
当然,目前为止我也搞不懂为什么环境对象是Null,这个问题大概留到以后吧。
2.怎么给事件处理函数绑定环境对象为实例化出来的组件
要达到这一目标,其实是有听多办法的,比如说
- 以箭头函数的方式定义一个事件处理函数,这样子做是最为省力的一种做法。缺点的话目前不知道。如下所示:
class Test extends Component{
constructor(props){
super(props)
}
clickHander = (event) => {
alert(Object.prototype.toString.call(this))//[object Object]
alert(event.target)//[object HTMLButtonElement]
}
render(){
return (
<div><button onClick = {this.clickHander}>click</button></div>
)
}
}
- 以普通函数的形式定义事件处理函数,接着再到构造函数里面对事件处理函数的执行环境进行硬绑定。如下所示:
class T0607_0 extends Component{
constructor(props){
super(props)
this.clickHander = this.clickHander.bind(this)
}
clickHander(event){
alert(Object.prototype.toString.call(this))//[object Object]
alert(event.target)//[object HTMLButtonElement]
}
render(){
return (
<div><button onClick = {this.clickHander}>click</button></div>
)
}
}
轻涛拍打着长堤,轻的就像张洁结的发丝。
她解开了束发的缎带,让晚风吹乱她的头发,吻在楚留香面颊上,脖子上。
发丝轻柔,轻的就像是堤下的浪涛。