當單擊我的頁面上的按鈕時,我試圖更新我的狀態變數。但是我發現我不能使用 react 類組件方法。這是最小的可重現示例。
import React, { Component } from 'react'
export class Name extends Component {
constructor(){
super();
this.state = {
name : "Farhan Ahmed"
}
}
clickMe() {
this.setState({
name:"Ahmed Farhan"
})
}
render() {
return (
<div>
<h1>{this.state.name}</h1>
<button className="btn btn-success" onClick={this.clickMe}>Change Text</button>
</div>
)
}
}
export default Name
錯誤 :
TypeError: Cannot read properties of undefined (reading 'setState')
但是當我用箭頭函式替換它時,它對我有用。
我的問題是為什么在這種情況下常規類方法不起作用,為什么我需要用箭頭函式替換它?
uj5u.com熱心網友回復:
當您嘗試訪問this關鍵字而不系結函式時,this關鍵字未定義。因此,您需要在建構式中系結該函式,或者使用確保this在該函式內系結的箭頭函式語法。您可以查看系結方法方法和箭頭函式的檔案
uj5u.com熱心網友回復:
按鈕沒有被點擊,但函式會在組件渲染時運行。
onClick={this.clickMe}
和這個;
onClick={() => this.clickMe}
功能僅在單擊按鈕時起作用。
閱讀:https : //beta.reactjs.org/learn/responding-to-events
uj5u.com熱心網友回復:
在此處找到的檔案https://reactjs.org/docs/handling-events.html中解釋了此錯誤以及可能的解決方案。如果您沒有使用檔案中提到的實驗性“公共類欄位語法”,您可以使用bind您的函式,也可以使用箭頭函式:
帶系結
onClick={this.clickMe.bind(this)}
箭頭函式
onClick={() => this.clickMe()}
這些是最常見的(我個人見過),但檔案也提供了更多的解決方案。
編輯
有人指出 OP 是在問“為什么”,而不一定是“我該如何解決?” 所以從上面鏈接的檔案中:
您必須小心
thisJSX 回呼中的含義。在 JavaScript 中,默認情況下不系結類方法。如果您忘記系結this.handleClick并將其傳遞給onClick,this將在實際呼叫函式時未定義。
這不是 React 特定的行為;它是 JavaScript 中函式如何作業的一部分。通常,如果您參考一個沒有 () 后的方法,例如
onClick={this.handleClick},則應該系結該方法。
uj5u.com熱心網友回復:
這個問題不是特定于反應的,而是實際上與 Javascript 的一般作業方式有關。
this在 javascript 中的功能略有不同。由于 React 是一個 javascript 庫,因此this在 React 中遵循相同的概念。
在javascript中,this關鍵字的行為基于函式的呼叫方式。this在 javascript 中保存對當前執行背景關系的參考。根據函式的呼叫方式, this 可以參考不同的物件。
如果使用這樣的物件呼叫函式,
obj.functionName()那么這將始終回傳對物件的參考如果一個函式作為獨立函式被呼叫,
functionName()那么這將回傳對 window 物件的參考,但如果啟用了嚴格模式,那么這將回傳 undefined。如果一個函式是一個從回呼中呼叫的類方法,
callback = obj.functionName(); callback();那么這將回傳 undefined。
現在我們更有興趣了解我們將類函式設定為回呼的第三點onClick。
讓我們通過一個例子來理解它
考慮具有以下方法的類 Rectangle
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
// Getter
area() {
console.log(this);
return this.calcArea();
}
// Method
calcArea() {
return this.height * this.width;
}
}
現在當我們這樣做時
const square = new Rectangle(10, 10);
square.area()
它給了我們預期的結果
Rectangle {height: 10, width: 10} /* value of this */
100
現在,當我們將相同的內容存盤在回呼中并呼叫回呼函式時
callback = square.area;
callback()
這給了我們錯誤:
undefined /* value of this */
VM106:9 Uncaught TypeError: Cannot read properties of undefined (reading 'calcArea')
at area (<anonymous>:9:17)
at <anonymous>:1:1
如您所見, this 的值未定義。這是因為 area 方法被重新定義了范圍并最終丟失了它的背景關系,即它的this關鍵字參考。你的情況也發生了同樣的事情。
解決方案 :
現在嘗試使用箭頭函式或將相同的函式系結到類,您將能夠成功呼叫回呼。
使用箭頭函式
area = () => {
console.log(this.width, this.height);
return this.calcArea();
}
使用箭頭函式的優點是它不會重新定義“this”關鍵字的范圍,從而無需在建構式中系結“this”
通過在建構式中系結函式
constructor(height, width) {
this.height = height;
this.width = width;
this.area = this.area.bind(this);
}
現在使用回呼呼叫相同的
const square = new Rectangle(10, 10);
callback = square.area;
callback()
會給我們結果
Rectangle {height: 10, width: 10, area: ?}
100
This is a good approach to bind event handlers but it will be a hectic task to repeat the same set of steps for each event handler.
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/334459.html
標籤:javascript html 反应 jsx 反应组件
