React組件中的this到底是指什么尘吗?看完這篇,再也不會(huì)有疑問浇坐。
-初步感受不同代碼位置睬捶,this打印什么。
-改變自定義方法的"調(diào)用者"近刘,看看this打印什么擒贸。
-該如何手動(dòng)綁定this臀晃。
編寫下面這個(gè)組件,將其渲染出來介劫。
import React from 'react';
const suffix = '被調(diào)用徽惋,this指向:';
export default class ReactThis extends React.Component {
handler() {
console.log(`handler${suffix}`, this)
}
render() {
console.log(`render${suffix}`, this)
return (
<div>
<h2 onClick={this.handler}>Hello React</h2>
</div>
);
}
}
結(jié)果是,render()函數(shù)中的this指向了組件實(shí)例座韵,而handler()函數(shù)中的this則是一個(gè)undefined险绘。
。
自定義方法的"調(diào)用者"不同導(dǎo)致this不同誉碴。("調(diào)用者"是指函數(shù)執(zhí)行時(shí)的當(dāng)前對(duì)象)
分別在組件自帶的生命周期函數(shù)以及自定義的handler()方法中打印this宦棺,并在render()方法里分別使用this.handler()、window.handler()黔帕、onClick={this.handler}這三種方法調(diào)用handler()代咸,看看this的指向。
import React from 'react';
const suffix = '被調(diào)用成黄,this指向:';
export default class ReactThis extends React.Component {
componentWillMount(){
console.log(`componentWillMount${suffix}`, this)
}
componentDidMount(){
console.log(`componentDidMount${suffix}`, this)
}
componentWillReceiveProps(){
console.log(`componentWillReceiveProps${suffix}`, this)
}
shouldComponentUpdate(){
console.log(`shouldComponentUpdate${suffix}`, this)
}
componentWillUpdate(){
console.log(`componentWillUpdate${suffix}`, this)
}
componentDidUpdate(){
console.log(`componentDidUpdate${suffix}`, this)
}
componentWillUnmount(){
console.log(`componentWillUnmount${suffix}`, this)
}
handler() {
console.log(`handler${suffix}`, this)
}
render() {
console.log(`render${suffix}`, this)
this.handler()
window.handler = this.handler;
window.handler();
return (
<div>
<h2 onClick={this.handler}>Hello React</h2>
</div>
);
}
}
運(yùn)行程序后發(fā)現(xiàn)呐芥,
render()以及componentWillMount()、componentDidMount()等其他生命周期函數(shù)中的this慨默,都是指向組件實(shí)例贩耐。
window.handler()中的this指向了window。
onClick={this.handler}中的this打印了undefined厦取。
沒有自動(dòng)綁定
如果this沒有指向組件實(shí)例潮太,是無法使用state等組件實(shí)例對(duì)象的屬性的。
但是React組件中沒有實(shí)現(xiàn)this的自動(dòng)綁定虾攻,函數(shù)的"調(diào)用者不同"導(dǎo)致this的指向不同铡买。具體this是指什么,React把這種上下文轉(zhuǎn)換的自由權(quán)交給了開發(fā)者霎箍。
手動(dòng)綁定this
1奇钞、在構(gòu)造函數(shù)里綁定
constructor(){
super()
this.state = {}
this.handler = this.handler.bind(this)
}
綁定之后,觸發(fā)點(diǎn)擊事件漂坏,this已經(jīng)指向組件實(shí)例了景埃。
在構(gòu)造函數(shù)里綁定this的好處是,僅需綁定一次顶别,避免每次渲染時(shí)都要重新綁定谷徙,函數(shù)在別處復(fù)用時(shí)也不需要再次綁定了。
2驯绎、在屬性中臨時(shí)綁定
render() {
console.log(`render${suffix}`, this)
this.handler()
window.handler = this.handler;
window.handler();
return (
<div>
<h2 onClick={this.handler.bind(this)}>Hello React</h2>
<div>value:{this.state.value}</div>
</div>
);
}
3完慧、使用箭頭函數(shù)
render() {
console.log(`render${suffix}`, this)
this.handler()
window.handler = this.handler;
window.handler();
return (
<div>
<h2 onClick={()=>{this.handler()}}>Hello React</h2>
<div>value:{this.state.value}</div>
</div>
);
}
箭頭函數(shù)會(huì)捕獲其所在上下文的this值,作為自己的this值剩失。
4屈尼、es7寫法
handler=()=> {
console.log(`handler${suffix}`, this)
}
render() {
console.log(`render${suffix}`, this)
this.handler()
window.handler = this.handler;
window.handler();
return (
<div>
<h2 onClick={this.handler}>Hello React</h2>
<div>value:{this.state.value}</div>
</div>
);
}
然而es6并不支持es7寫法册着,不過沒關(guān)系,安裝一個(gè)babel-preset-stage-0
配置一下.babelrc脾歧,就可以支持了甲捏。
"presets": [
"es2015",
"stage-0",
"react"
],
這么多手動(dòng)綁定this的方法,推薦 1涨椒,3摊鸡,4。
外傳:
var person = {
speak: function() {
console.log(this)
}
}
person.speak();
var _speak = person.speak;
_speak()
person.speak() this指向什么蚕冬?
_speak()this指向什么?
又一個(gè)外傳:
var person = {
speak: ()=> {
console.log(this)
}
}
person.speak();
var _speak = person.speak;
_speak()
person.speak() this指向什么是辕?
_speak()this指向什么囤热?