问题描述
令我困惑的是,为什么当我定义一个反应组件类时,这个
对象中包含的值在定义的方法( this)中未定义
在生命周期方法中可用),除非我使用 .bind(this)
或使用箭头函数定义方法,例如在以下代码 this.state
将在 renderElements
函数中未定义,因为我没有使用箭头函数定义它,并且没有使用 .bind(this)
class MyComponent extends React.Component {
constructor(){
super();
this.state = {elements:5}
}
renderElements(){
const output = [];
//在下面的这个.state.elements将被定义为
//因为我在构造函数
//示例中没有使用.bind(this)这个方法:this.renderElements = this.renderElements.bind(this)
for(let i = 0; i< this.state.elements; i ++){
output.push(< div key = {i} />);
}
返回输出;
}
// .this在生命周期方法中定义,
//因此不需要在render方法上调用.bind(this)。
render(){
return(
< div onClick = {this.renderElements}>< / div>
);
}
}
然后在以下示例中,我不需要使用 .bind(this)
或箭头功能此
可在中提供
function
class Animal {
constructor(name){
this.name =名字
}
speak(){
console.log(this.name +'make a noise。
}
}
class Dog extends Animal {
speak(){
console.log(this.name +'barks。
}
}
var d =新狗('Mitzie');
d.speak();
为了澄清,我的问题是两部分。一)为什么在第二个代码示例中,我不需要调用 .bind(this)
到 speak
但是我在React组件中为 renderElements
函数和Two)为什么生命周期方法(render,componentDidMount等)已经可以访问类'这个
对象,但 renderElements
不。
在React文档中说如下
但是很明显,他们做的是我发布的第二个代码示例。
更新
前两个注释中的两个链接都显示了一个不使用 .bind(this)
在类方法上,它工作正常。但是在文档中还是明确地说你需要绑定你的方法,或者使用一个箭头函数。在使用gulp和babel的项目中,我可以复制。这是否意味着浏览器有更新的东西?
更新2
我的初始代码示例有 this.renderElements()
直接在render函数中调用。这将按预期的方式工作,而不需要绑定函数,或者用箭头函数定义它。当我将函数作为 onClick
处理程序时,会出现此问题。
组件中的事件处理程序不会像其他方法(生命周期方法...)自动绑定到组件实例。
class MyComponent extends React.Component {
render(){
return(
< div onClick = {this.renderElements}>
{this.renderElements()}< ; - ```仍然在MyComponent上下文
< / div>
)
}
}
//在引擎底下
var instance = new MyComponent();
var element = instance.render();
//点击div
element.onClick()< - `this`里面的renderElements指的是现在的窗口对象
查看此示例以了解此
更多:
class Animal {
constructor(name){
this.name = name;
}
speak(){
console.log(this.name +'make a noise。
}
}
class Dog extends Animal {
run(){
console.log(this.name +'runs');
}
speak(){
console.log(this.name +'barks。
this.run(); < - `这个`仍然在狗的上下文
return {onRun:this.run};
}
}
var d =新狗('Mitzie');
var myDog = d.speak();
myDog.onRun()< - `this`现在在全局上下文中,这是`window`对象
您可以查看这个获取更多信息。
Something that is puzzling me is why when I define a react component class, values contained in the this
object are undefined in methods defined (this
is available in lifecycle methods) within the class unless I use .bind(this)
or define the method using an arrow function for example in the following code this.state
will be undefined in the renderElements
function because I did not define it with an arrow function and did not use .bind(this)
class MyComponent extends React.Component {
constructor() {
super();
this.state = { elements: 5 }
}
renderElements() {
const output = [];
// In the following this.state.elements will be undefined
// because I have not used .bind(this) on this method in the constructor
// example: this.renderElements = this.renderElements.bind(this)
for(let i = 0; i < this.state.elements; i ++){
output.push(<div key={i} />);
}
return output;
}
// .this is defined inside of the lifecycle methods and
// therefore do not need call .bind(this) on the render method.
render() {
return (
<div onClick={this.renderElements}></div>
);
}
}
Then in the following example I do not need to use .bind(this)
or an arrow function, this
is available as expected in speak
function
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + ' makes a noise.');
}
}
class Dog extends Animal {
speak() {
console.log(this.name + ' barks.');
}
}
var d = new Dog('Mitzie');
d.speak();
http://jsbin.com/cadoduxuye/edit?js,console
To clarify, my question is two part. One) why in the second code example do I not need to call .bind(this)
to the speak
function, but I do in the React component for the renderElements
function and Two) why do the lifecycle methods (render, componentDidMount, etc) already have access to the class' this
object, but renderElements
does not.
In the React docs it says the following
But clearly they do, as the second code example I've posted shows.
Update
Both links in the first two comments show a working example of React classes NOT using .bind(this)
on class methods and it works fine. But still in the docs is explicitly says you need to bind your methods, or use an arrow function. In a project using gulp and babel I can reproduce. Could it mean browsers have updated things?
Update 2
My initial code example had this.renderElements()
called directly in the render function. That would work as expected without binding the function, or defining it with an arrow function. The issue occurs when I put the function as an onClick
handler.
Event handlers in the component will not be bound automatically to the component instance like other methods ( life cycle methods...).
class MyComponent extends React.Component {
render(){
return (
<div onClick={this.renderElements}>
{this.renderElements()} <-- `this` is still in side the MyComponent context
</div>
)
}
}
//under the hood
var instance = new MyComponent();
var element = instance.render();
//click on div
element.onClick() <-- `this` inside renderElements refers to the window object now
Check this example to understand this
more :
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + ' makes a noise.');
}
}
class Dog extends Animal {
run(){
console.log(this.name + ' runs');
}
speak() {
console.log(this.name + ' barks.');
this.run(); <-- `this` is still in the Dog context
return {onRun : this.run};
}
}
var d = new Dog('Mitzie');
var myDog = d.speak();
myDog.onRun() <-- `this` is now in the global context which is the `window` object
You can check this article for more information.
这篇关于为什么我必须.bind(this)用于在React组件类中定义的方法,但不是在常规的ES6类中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!