我们已经知道在JS中:ES5的this是谁调用就指向谁,箭头函数的this是在哪里定义就指向谁
下面看看三种React组件中的this是什么,并且为什么会这样。
- function定义的函数组件
- const定义的函数组件
- Class组件
普通函数组件 fucntion () {}
function ThisTest () {
console.log('this', this)
return (
<div>Hello, ThisTest</div>
)
}
// this undefined
JS module中自动使用strict模式,故依然是undefiend,而非global
- Also, note that you might get different behavior from sections of script defined inside modules as opposed to in standard scripts. This is because modules use strict mode automatically.
<script>
console.log('script1', this) // Window
</script>
<script type="module">
console.log('script2', this) // undefined
</script>
箭头函数组件 const
import React from 'react'
console.log('Module this:', this)
const ThisTest = () => {
console.log('ThisTest this:', this)
return (
<div>Hello, ThisTest</div>
)
}
// Module this: undefined
// ThisTest this: undefined
因为箭头函数定义在js模块中,而顶层js模块的的this就是undefined。在组件外输出this依然为undefined。
当然,函数组件并不需要使用this,真正有使用场景的还是class组件。
class组件
我们知道class组件的函数有两种绑定this至组件的方法:
// 1: bind绑定this
constructor (props) {
super(props)
this.handleClick = this.handleClick.bind(this)
}
// 2: 使用箭头函数
handleClick = () => { /.../ }
若不绑定,函数里的this会指向undefined。
class ThisTest extends React.Component {
handleClick () {
console.log('click', this)
}
render () {
return (
<div onClick={this.handleClick}>Hello, ThisTest</div>
)
}
}
但为什么是undefined呢?onClick={this.handleClick}
会作为React合成事件转换成addEventlistener
,但是addEventListener的回调函数里的this不是指向绑定函数的DOM元素吗?
1.当我们查看React-dom有关合成事件的源码,就可知(TODO!)
this.handleClick不是作为addEventListener的回调函数,而是回调函数的一部分。在回调里调用的函数即为匿名函数的调用,会指向global。
const h = function () {
console.log('bbbbbbbb', this) // Window
}
document.getElementById('root').addEventListener('click', function () {
console.log('cccccccc', this) // <div></div>
h()
})
2.综上那this.handleClick会指向global吗?并没有,handleClick是class里定义的函数。Class内部定义会使用strict模式,所以handleClick则指向undefined。
The body of a class is executed in strict mode, ——MDN - Classes