本文介绍了为什么我必须.bind(this)用于在React组件类中定义的方法,但不是在常规的ES6类中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

令我困惑的是,为什么当我定义一个反应组件类时,这个对象中包含的值在定义的方法( 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类中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-13 11:37