在使用類方式創(chuàng)建組件時(shí),類中定義一個(gè)函數(shù),并且綁定到元素的點(diǎn)擊事件上,此時(shí)這個(gè)函數(shù)中this指向并不是當(dāng)前這個(gè)組件。
組件代碼如下:
class App extends React.Component {
// 組件數(shù)據(jù)
constructor() {
super()
this.state = {
message: 'hello world',
}
}
// 點(diǎn)擊函數(shù)
btnClick() {
this.setState({
message: 'hello react',
})
}
// 渲染函數(shù)
render() {
return (
<div>
<h2>{this.state.message}</h2>
<button onClick={this.btnClick}>
修改文本
</button>
</div>
)
}
}
如上代碼中,點(diǎn)擊修改文本按鈕,會發(fā)生如下報(bào)錯(cuò)
Uncaught TypeError: Cannot read properties of undefined (reading 'setState')
提示 undefined
找不到 setState
方法。
主要原因如下:
- 默認(rèn)情況下
btnClick
內(nèi)的this
是綁定的是undefined
,熟悉this綁定的應(yīng)該知道,this是綁定運(yùn)行時(shí)調(diào)用這個(gè)函數(shù)的對象,this綁定詳解可以查看:https://www.cnblogs.com/easy1996/p/17954257; - 在正常的DOM操作中,監(jiān)聽點(diǎn)擊,調(diào)用監(jiān)聽函數(shù)的其實(shí)是節(jié)點(diǎn)對象,比如上面的按鈕對象;
- 在React中,并不是直接渲染真實(shí)的DOM,render渲染函數(shù)中所編寫的button只是一個(gè)語法糖,最終會編譯成
React.createElement("button", {onClick: this.btnClick})
; - 同時(shí)會將
btnClick
函數(shù)暴露出來,以const click = onClick(偽代碼)
的形式; - 當(dāng)點(diǎn)擊事件觸發(fā)時(shí),react執(zhí)行上面的
click
函數(shù),默認(rèn)里面this
就是綁定的undefined
,相當(dāng)于window中調(diào)用函數(shù)(嚴(yán)格模式下為undefined
);
解決方法:
知道了問題在于 this
的綁定不對,有三種方式解決:
1.給點(diǎn)擊函數(shù)顯式綁定 this
class App extends React.Component {
constructor() {
super()
this.state = {
message: 'hello world',
}
// 位置1.在此處重新給點(diǎn)擊函數(shù)綁定this為組件對象
this.btnClick = this.btnClick.bind(this)
}
btnClick() {
this.setState({
message: 'hello react',
})
}
render() {
return (
<div>
<h2>{this.state.message}</h2>
{/* 位置2.直接在渲染函數(shù)中重新綁定this */}
<button onClick={this.btnClick.bind(this)}>
修改文本
</button>
</div>
)
}
}
在上面兩個(gè)位置任選一個(gè)重新綁定 this
為組件對象即可。
2.使用 ES6 class field
class App extends React.Component {
constructor() {
super()
this.state = {
message: 'hello world',
}
}
// class field
btnClick = () => {
this.setState({
message: 'hello react',
})
}
render() {
return (
<div>
<h2>{this.state.message}</h2>
<button onClick={this.btnClick}>修改文本</button>
</div>
)
}
}
上面使用 class field
的方式,給 btnClick
賦值一個(gè)箭頭函數(shù),箭頭函數(shù)默認(rèn)綁定當(dāng)前環(huán)境的 this
。
3.直接在按鈕上使用箭頭函數(shù)(推薦)文章來源:http://www.zghlxwxcb.cn/news/detail-776967.html
class App extends React.Component {
constructor() {
super()
this.state = {
message: 'hello world',
}
}
btnClick() {
this.setState({
message: 'hello react',
})
}
render() {
return (
<div>
<h2>{this.state.message}</h2>
{/* 直接綁定箭頭函數(shù) */}
<button onClick={() => this.btnClick()}>修改文本</button>
</div>
)
}
}
再看一下此時(shí)執(zhí)行的流程:文章來源地址http://www.zghlxwxcb.cn/news/detail-776967.html
-
onClick
綁定的是一個(gè)箭頭函數(shù),箭頭函數(shù)的this
綁定的是App組件對象; - 前面的兩個(gè)例子中是將這個(gè)函數(shù)引用賦值給
onClick
,等待按鈕事件點(diǎn)擊,然后再觸發(fā)這個(gè)引用的函數(shù),onClick={this.btnClick}
; - 而上面的代碼中,是
onClick={() => this.btnClick()}
,是將() => this.btnClick()
這個(gè)箭頭函數(shù)賦值給onClick
,按鈕點(diǎn)擊觸發(fā)這個(gè)箭頭函數(shù),而箭頭函數(shù)內(nèi)部是一個(gè)已經(jīng)調(diào)用過的btnClick()
函數(shù),包含()
,調(diào)用時(shí)在箭頭函數(shù)內(nèi)部,所有this
綁定的是App
組件對象。
到了這里,關(guān)于react 事件函數(shù)中 this 綁定問題的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!