React事件处理函数在不使用bind()的情况下工作

时间:2018-05-31 03:18:40

标签: reactjs

我正在学习React,我遇到了事件处理程序。在React中,建议在将函数用作事件处理程序之前将函数绑定到this。但是,我没有绑定它,我仍然得到所需的输出。以下是我的代码:

import React, { Component } from 'react';

class Experiment extends Component {
    constructor(props){
        super(props);

    }

    clickEvent(e){
            e.preventDefault();
            document.getElementById('change').innerHTML="This text changed";
        }

    render(){
        return(
            <div>
                <p id='change'>This paragraph will change</p>
                <button onClick={this.clickEvent}>Press me</button>
            </div>
            );
    }
}

export default Experiment;

正如您所看到的,我没有将clickEvent()绑定到this,但onClick事件无故障地运行。这是为什么?我以为我会遇到undefined错误或其他错误

3 个答案:

答案 0 :(得分:3)

这样做的原因是因为你没有提到任何使用&#39;这个&#39;在clickEvent函数中。 在javascript中,&#39; this&#39;函数中的变量指的是调用函数的对象。

要证明这一点,请尝试访问this.propsthis.state,因为您遗漏了.bind(this)

,他们会返回未定义的内容

.bind()将返回一个新函数,它将坚持给定的&#39;这个&#39;上下文,无论它来自何处。

const myObj = {
    name: 'John',
    testFunction: function() {
        console.log(this.name);
    }
};

const testFunction = myObj.testFunction;

myObj.testFunction(); // John
testFunction(); // undefined


const testFunctionBound = testFunction.bind(myObj);
testFunctionBound(); // John

答案 1 :(得分:1)

作为Jye Lewis对上述答案的理论旁注,以及对该主题的澄清。

有三种常规方法可以将上下文绑定到函数中:

  1. 绑定(通常在构造函数中)
  2. 带箭头的类字段/属性
  3. 渲染中的箭头
  4. 示例代码:

    class ThisDemo extends Component {
      constructor(props) {
        super(props); 
    
        // 1. In constructor 
        this.onClick = this.onClick.bind(this);
      }
    
      // 2. Class field/property with arrow
      onClick = () => {  
      }
    
      render() {
        // 3. Arrow in render
        return (
          <button type="button" onClick={event => console.log(event)}>
            Pretty Button
          </button>
        ); 
      }
    }
    export default ThisDemo; 
    

    上下

    1. 绑定(通常在构造函数中)
      • ups:无论N多大,都在相同的原型上。
      • 赞成:污染构造函数
    2. 带箭头的类字段/属性
      • ups:非常方便,语法很好。对于N个组件,创建N个不同的功能
      • 降级:在某些情况下,性能下降。 (N high)
    3. 渲染中的箭头
      • ups:可以以简单的方式捕获事件,有利于执行逻辑而不传递回调参数的道具。
      • down:您正在为每个渲染传递一个新的内联箭头功能。始终是新引用,可能会导致重新呈现。
    4. 智慧

      如果你要传递函数,你应该只绑定.bind()或箭头函数。

      带箭头的类字段/属性很方便,但如果有许多This.Demo组件

      ,效率可能会很低

      要实事求是直到你不能成为。性能问题几乎从来都不是问题,它们可能会改变未来的工作方式。

      参考

      1. This article帮助我理解了不同的方法。
      2. 另外this one

答案 2 :(得分:0)

您可以使用箭头函数代替创建构造函数并同时调用super

bind方法。

  

箭头函数没有自己的this,但是有this   封闭执行上下文的值。词法箭头功能   绑定它们的上下文,因此这实际上是指原始上下文。   如果您要命名的话,这称为词汇范围。基本上,   这样可以避免我们在代码中执行.bind(this)。请注意,这是一个   JS中的实验性功能,这表示尚未被JS接受   ECMAScript标准

所以,不要这样做:

//with binding in a constructor and calling super method
class Experiment extends Component {
  constructor(props) {
    super(props); 

    // 1. In constructor 
    this.onClick = this.onClick.bind(this);
  }
...
}

您可以按照以下更简洁的方式进行操作:

  //with arrow 
  handleOnClick = product => {  
     ...
  }

在您的render方法中,您可以执行以下操作:

class Experiment extends Component {
  render() {
    return (
        <button onClick={ () => this.handleOnClick(product) } >
            Add new product
        </button>
    );
  }
}

Read more about arrow functions in this article: