![](/img/trans.png)
[英]why are we binding 'this' keyword for event handlers in react class components?
[英]'this' context different for event handlers in function vs class react components
為什么'this'(上下文)會根據我在反應中使用功能組件還是 class 組件而有所不同? 我了解綁定的工作原理,並且我的處理程序將采用 onclick 處理程序的上下文(或者它在 onclick 中使用),但我不明白為什么這兩種情況的值不同。 功能組件打印 window object 而 class 組件打印未定義。
如何定義合成 onclick 事件? 它的背景是什么? 它的回調有什么作用?
export default function App() {
const handleClick = function () {
console.log(this);
};
return (
<div className="App">
<button onClick={handleClick}>HandleClick Functional</button>
<Toggle />
</div>
);
}
class Toggle extends React.Component {
handleClick() {
console.log(this);
}
render() {
return <button onClick={this.handleClick}>HandleClick Class</button>;
}
}
代碼框鏈接: https://codesandbox.io/s/onclick-context-test-ievog6?file=/src/App.js
TL;DR - 這看起來像 CodeSandbox 的一個錯誤。 您的 React function 組件代碼最終以非嚴格模式運行,這導致您的this
值默認為全局 object 而不是應為的undefined
。
這種行為很奇怪。 但就像qrsngky在上面的評論中正確指出的那樣,問題主要與嚴格模式有關,並且是 CodeSandbox 如何進行錯誤處理的結果。 下面我概述了我對您的代碼為何如此運行的觀察。
使用function
關鍵字聲明的函數有自己的this
值(它們自己的“this 綁定”)。 如何確定this
值取決於 function 的執行方式。 .call( .call()
和.apply()
等方法能夠為它們執行的 function 設置this
值。
在嚴格模式代碼中,使用fn.apply(undefined)
會導致執行 function fn
並將fn
中的this
值設置為undefined
。 但是,在非嚴格模式代碼中,使用fn.apply(undefined)
會導致this
值設置為全局 object ,在瀏覽器中為window
object。 當 React 調用您的onClick
處理程序 function ( func
) 時,它通過執行func.apply(context, ...)
來調用它,並將context
設置為undefined
(您可以通過調試器看到這一點):
此時,您可能會認為您的代碼在任何地方都沒有使用"use strict"
指令,因此當您的 function 使用this
of undefined
調用時,它默認為全局 object window
。 但是,它並不像那樣簡單;)。 雖然看起來您的任何代碼都沒有在嚴格模式下運行,但實際上它被歸類為嚴格模式代碼。 那是因為ES6 模塊(您編寫反應代碼的內容) 會自動在 strict-mode 下運行。 同樣, 類也自動以嚴格模式運行。 所以這就引出了一個問題,即為什么你的代碼顯示window
那么你的代碼是否真的應該在嚴格模式下運行。
編寫 React 代碼時,需要將其轉換為瀏覽器可以理解和執行的代碼。 似乎發生的事情是,當您的反應代碼被轉譯時,CodeSandbox 在您的反應代碼周圍添加了一個try-finally 包裝器(您可以使用禁用源映射的調試器看到這一點):
try {
"use strict";
...
function App() {
const handleClick = function() {
console.log(this);
}
}
...
} finally {
...
}
我們可以看到 CodeSandbox 嘗試將您的代碼包裝在 try-finally 塊中,其中try
塊以“嚴格模式”運行,以嘗試匹配最初編寫代碼的 ES6 模塊自動應用的相同嚴格模式行為。但是,在與 function 無關的塊{}
中應用"use strict"
對代碼的嚴格性沒有影響(有關嚴格模式的規則,請參見 此處)。 因此,CodeSandbox 應用的 try-finally 包裝器最終會以非嚴格/草率模式運行您的代碼。 當 React 使用undefined
調用您的 onClick 處理程序時,這將導致this
為window
。
另一方面,您的class
仍然按預期工作,因為在轉譯的代碼中它仍然是class
,因此圍繞類的嚴格模式行為仍然存在,因此您會看到undefined
的預期。
但是,在使用 React 功能組件時,您不需要參考this
,而是可以使用諸如useState()
類的鈎子來管理諸如 state 之類的東西。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.