我知道在使用React类方法时,箭头函数是锁定this
的好方法。例如,我可能有一个点击处理程序:
clickHandler = () => {
// some code using 'this'
// eg this.state
}
// ... and in the render method
<button onClick={() => this.clickHandler()}>Test Button</button>
但是,如果我要使用非箭头函数语法,则哪个对象拥有代码?也就是说,this
是什么?
我尝试了以下操作,但Typescript无法编译:
clickHandler = function() {
console.log(this); // also tried to coerce this as any type
}
// Error: 'this' implicitly has type 'any' because it does not have a type annotation.ts(2683)
答案 0 :(得分:1)
您的“ this”将为“ undefined”,因为React在后台调用了您的函数,并且doesn't
从对象实例(IE MyComponent.onClickHandler(e)
)调用了它,就像这样{{1} }
在没有React参与的情况下发生的事情的简化模型看起来像这样.....
(onClickHandler(e))
用于解决此问题的方法是将函数的“ this”绑定到组件I.E的构造函数中。
class FakeReactComponent {
myName() {
console.log(this);
}
}
// this is what you give a onClick prop on an element.
const functionPassedToOnClick= new FakeReactComponent().myName;
console.log(
functionPassedToOnClick() // this is how react calls it (this is undefined)
)
实际上,这是在constructor(props: IProps) {
super(props);
this.onClickHandler = this.onClickHandler.bind(this);
}
中为React Components定义所有函数的“最佳实践”方法,因为箭头函数没有出现在类原型上,因此将为该函数的每个新React实例创建新函数。零件;但是,使用非箭头功能时,每个实例都在原型上,因此可以为每个React组件实例重复使用。
像autobind这样的技巧也不是最佳实践,因为绑定每个函数的class
是不必要的,因为只有React调用的函数需要绑定this
,并且有99%的时间是唯一的函数作为事件处理程序。
答案 1 :(得分:1)
这取决于您如何调用函数以及是否绑定它。
class Test extends React.Component {
clickHandler = function() {
console.log(this);
}
render() {
return (
<div>
<button onClick={this.clickHandler}>Option A</button>
<button onClick={this.clickHandler.bind(this)}>Option B</button>
<button onClick={() => this.clickHandler()}>Option C</button>
</div>
);
}
}
通过Option A
按钮,点击处理程序将直接传递到<button />
元素。由于React假设您绑定了this
并且不会为您这样做,所以this
中的clickHandler
将是undefined
。
使用Option B
按钮将this.clickHandler
明确绑定到this
,在这种情况下,this
中的clickHandler
将引用该特定实例Test
组件。
对于Option C
(这是您在做的问题),我们没有将this.clickHandler
设置为onClick
处理程序,但是我们正在定义新箭头调用 this.clickHandler
的功能。在这种情况下,新箭头功能将自动将Test
组件获取为this
,并将其传递到clickHandler
。
请注意,Option A
版本将允许组件显式绑定处理程序:
class Button extends React.Component {
render() {
return (
<button
onClick={this.props.onClick.bind(this)}
children={this.props.children}
/>
);
}
}
class Test extends React.Component {
clickHandler = function() {
console.log(this);
}
render() {
return <Button onClick={this.clickHandler}>Click</Button>;
}
}
在这种情况下,this
中的Test.clickHandler()
实际上是对Button
实例的引用。