这是我的第一个React App(react@16.8.1 )。我试图找出为什么在使用基于功能的组件与基于类的组件时onClick事件的处理方式不同。
据我所知,我应该使用基于类的c。只有当我需要更改状态时,对吗?
基于功能的组件会抛出_this is undefined error
但基于类-不会。
在两种情况下,我都使用箭头功能而不是绑定功能。
基于功能:
import React from 'react';
const AnswersDisplay = (props) => {
// even with bind I still get "_this is undefined"
//this.onAnswer = this.onAnswer.bind(this);
const answerList = props.answerList.map( (option) => {
return (
<button
onClick={this.onAnswer}
value={option}
className="ui basic green button">{option}
</button>
)
});
const onAnswer = (e) =>{
console.log(e.target.value);
}
return(
<div className="ui two buttons hSpace">{this.answerList}</div>
);
};
export default AnswersDisplay;
vs基于类的作品。
import React from 'react';
class AnswersDisplay extends React.Component {
constructor(props) {
super(props);
//this.onAnswer = this.onAnswer.bind(this);
}
answerList = this.props.answerList.map( (option) => {
return (
<button
onClick={this.onAnswer}
value={option}
className="ui basic green button">{option}
</button>
)
});
onAnswer = (e) =>{
console.log(e.target.value);
}
render() {
return(
<div className="ui two buttons hSpace">{this.answerList}</div>
);
}
};
export default AnswersDisplay;
答案 0 :(得分:0)
对于功能组件,您要声明一个常量,并在其中保留一个函数。单击按钮时要呼叫的对象。但是,请确保在函数中使用this
。在这种情况下,this
将引用全局执行上下文,并且在该特定上下文中,JavaScript引擎将无法找到属性onAnswer
,因此它将返回undefined
。
为使这项工作有效,您不带this
就回叫了。
喜欢:
onClick={onAnswer}
整个代码如下:
import React from 'react';
const AnswersDisplay = (props) => {
// even with bind I still get "_this is undefined"
//this.onAnswer = this.onAnswer.bind(this);
const answerList = props.answerList.map( (option) => {
return (
<button
onClick={onAnswer}
value={option}
className="ui basic green button">{option}
</button>
)
});
const onAnswer = (e) =>{
console.log(e.target.value);
}
return(
<div className="ui two buttons hSpace">{this.answerList}</div>
);
};
答案 1 :(得分:0)
此MDN web doc涵盖了您需要了解的有关this
的所有信息。
为简单起见,请考虑objects
,其中this
是“未定义”的,除非:
object
绑定到bind(this)
(请参见下面的注释),或者通过将外部函数与object
重新绑定而在object
之外反弹。本身:bind(obj)
。 注意:如下所示(在method6中),有一个例外,即在arrow functions
中使用ES5 object
意味着它将保留封闭的词法范围{ 1}},无需约束。
例如:
this
关于this.prop = "global prop"
const outsideArrowFunction = () => (this.prop)
function outsideFunction() {
return this.prop;
};
const obj = {
prop: "obj's prop",
method: function() {
return this.prop; // returns "obj's prop"
},
method2: function() {
return this; // returns the entire "obj" and its properties
},
method3: function() {
return this.method(); // returns "obj's prop"
},
method4: function() {
return outsideFunction(); // returns "global prop" because the outsideFunction's lexical scope doesn't recognize the "obj"'s nor its properties
},
method5: function() {
return outsideArrowFunction(); // same as method4, utilizes global this
},
method6: function() {
const x = () => this.method();
return x(); // returns "obj's prop" because arrow functions take on "this" from the "obj"
},
method7: function() {
const x = function() {
return this.prop;
};
return x(); // returns "global prop" because "this" loses lexical scope upon execution
},
method8: function() {
const x = this.method.bind(this);
return x(); // returns "obj's prop" because "this" refers to the "obj" upon execution
},
method9: function(callback) {
return callback(this.method);
},
method10: function() {
return this.method9(function(callback) {
return callback(); // returns "global prop" because "this" loses lexical scope upon execution
});
}
};
const a = outsideArrowFunction.bind(obj); // returns "global prop" because arrow functions take on whatever "this" is upon its creation, so "this" refers to the global "this"
const b = outsideFunction.bind(obj); // returns "obj's prop" since a traditional function can rebind "this", which has been rebound to "obj"
console.log(`Method: ${obj.method()}`);
console.log(`Method2: ${obj.method2()}`);
console.log(`Method3: ${obj.method3()}`);
console.log(`Method4: ${obj.method4()}`);
console.log(`Method5: ${obj.method5()}`);
console.log(`Method6: ${obj.method6()}`);
console.log(`Method7: ${obj.method7()}`);
console.log(`Method8: ${obj.method8()}`);
console.log(`Method10: ${obj.method10()}`);
console.log(`arrowFunction: ${a()}`);
console.log(`outsideFunction: ${b()}`);
,它们是classes
的模板。因此,除非类objects
已绑定在this
中或您使用undefined
,否则this
将是method
或是全局constructor
。通过单击每个按钮来尝试下面的示例,请注意所有三种方法如何如何工作,但它取决于它们的调用方式:
arrow function
class Example extends React.Component {
constructor() {
super();
this.state = { method: "" };
this.boundMethod = this.boundMethod.bind(this);
}
componentDidMount() {
this.unboundMethod();
};
boundMethod() {
this.setState({ method: "Bound Method" }); // this works because the method is bound to the class
}
unboundMethod() {
try {
this.setState({ method: "Unbound Method" }); // this only works if it's called within a bound method class (like componentDidMount)
} catch (err) {
alert(err); // however, if it's called within a callback (like in an onClick event), it fails.
}
}
arrowMethod = () => {
this.setState({ method: "Arrow Method" }); // this works because arrow methods are automatically bound to the class
};
render() {
return (
<div>
<button onClick={this.boundMethod}>Bound Method</button>
<button onClick={this.unboundMethod}>Unbound Method</button>
<button onClick={this.arrowMethod}>Arrow Method</button>
<p>The {this.state.method} was called</p>
</div>
);
};
}
ReactDOM.render(<Example />, document.body);