【发布时间】:2019-11-19 12:20:00
【问题描述】:
我在 Codeacademny 上 ReactJS 课程,他们让我很困惑。
(编辑 - 完整代码)代码照片:
对于scream 类方法,没有构造函数或任何地方调用任何绑定方法。
但是在进一步的练习中,他们告诉你不能这样做。
我可能错过了什么。
【问题讨论】:
-
真的要看函数是怎么定义的,做什么的。
标签: javascript reactjs jsx
我在 Codeacademny 上 ReactJS 课程,他们让我很困惑。
(编辑 - 完整代码)代码照片:
对于scream 类方法,没有构造函数或任何地方调用任何绑定方法。
但是在进一步的练习中,他们告诉你不能这样做。
我可能错过了什么。
【问题讨论】:
标签: javascript reactjs jsx
显然this.scream 是一个箭头函数。箭头函数不需要绑定。它默认指向正确的上下文。
scream = () => { ... }
【讨论】:
this指向实例。
scream = () => { ... }
render() {
return <button onClick={()=>this.scream()}>AAAAAH!</button>;
}
【讨论】:
this.scream是箭头函数,所以() => this.scream()和this.scream是一样的。跨度>
你必须小心 JSX 回调中 this 的含义。在 JavaScript 中,默认情况下不绑定类方法。如果忘记绑定 this.handleClick 并传递给 onClick,那么在实际调用函数时 this 将是未定义的。
这不是 React 特有的行为;它是 JavaScript 中函数工作方式的一部分。一般如果引用的方法后面不带(),比如
onClick={this.handleClick},你应该绑定那个方法。
当您使用 ES6 类定义组件时,常见的模式是事件处理程序成为该类的方法。例如,这个 Toggle 组件呈现了一个按钮,让用户可以在“ON”和“OFF”状态之间切换:
class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = {isToggleOn: true};
// This binding is necessary to make `this` work in the callback
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(state => ({
isToggleOn: !state.isToggleOn
}));
}
render() {
return (
<button onClick={this.handleClick}>
{this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
);
}
}
ReactDOM.render(
<Toggle />,
document.getElementById('root')
);```
【讨论】:
您可以简单地使用箭头函数(无需在构造函数中绑定)。
scream = () => { console.log('Here') }
render() {
return <button onClick={this.scream}>AAAAAH!</button>;
}
或者你可以内联调用这个函数。
render() {
return <button onClick={() => console.log('Here')}>AAAAAH!</button>;
}
【讨论】:
您应该使用箭头函数进行事件处理,将函数绑定到对象。其他解决方案是在构造函数中自动绑定每个函数,例如:
class Test{
constructor(){
Object.getOwnPropertyNames(Test.prototype).forEach(
method => this[method] = this[method].bind(this));
}
阅读 @AutoBind 装饰器了解更多详情。
【讨论】:
并且没有构造函数或任何地方调用任何用于尖叫类方法的绑定方法。
当方法内部实际使用this时,您只需要将this绑定到组件实例。
在你的例子中不是这样,所以不需要绑定它。无论方法如何执行,它总是会产生相同的输出。
下面是一个没有 React 的例子来说明区别:
var obj = {
value: 42,
method1() { // doesn't use `this`
console.log("yey!");
},
method2() { // uses `this`
console.log(this.value);
},
};
obj.method1(); // works
obj.method2(); // works
var m1 = obj.method1;
var m2 = obj.method2;
m1(); // works
m2(); // BROKEN!
var m2bound = obj.method2.bind(obj);
m2bound(); // works
【讨论】:
new SomeClass() 时,您正在创建该类(一个对象)的新 instance。方法通常在实例上调用,方法可以通过this 引用实例。你问为什么方法没有绑定(到组件实例),所以这就是我的回答。
new Someclass()。更类似于这个obj.method1();