为什么在使用ES6和ReactJS时需要使用bind?

9

在ReactJS中使用ES5进行开发,一个组件可以被定义为以下内容:

var MyComponent = React.createClass({
  alertSomething: function(event) {
    alert(event.target);
  },

  render: function() {
    return (
      <button onClick={this.alertSomething}>Click Me!</button>
    );
  }
});

ReactDOM.render(<MyComponent />);

在这个例子中,this代表对象本身,这是预期的自然行为。 问题 我的问题是:
你如何使用ES6创建组件?
class MyComponent extends React.Component {
  constructor(props) {
    super(props);
  }

  alertSomething(event) {
    alert(event.target);
  }

  render() {
    return (
      <button onClick={this.alertSomething.bind(this)}>Click Me!</button>
    );
  }
}

ReactDOM.render(<MyComponent />);

在JavaScript中,使用new运算符时,this引用实例化的对象本身,那么有人能告诉我使用bind的真正目的是什么吗?这与React的内部机制有关吗?


1
bind 只是核心 JavaScript。它是事件绑定的工作方式,而不是 React 的概念。 - mnsr
1
不是的。这是React.createClass的魔法 - ES6的行为才是自然的行为。 - Bergi
3个回答

2

bind在React ES6类中的一个目的是需要手动绑定this。

没有自动绑定

方法遵循常规ES6类的语义,这意味着它们不会自动将this绑定到实例。您必须显式地使用.bind(this)或箭头函数=>:

我们建议您在构造函数中绑定事件处理程序,以便它们仅针对每个实例绑定一次:

constructor(props) {
  super(props);
  this.state = {count: props.initialCount};
  this.tick = this.tick.bind(this);  // manually binding in constructor
}

你可以在文档中阅读更多信息:https://facebook.github.io/react/docs/reusable-components.html

2
var cat = {
  sound: 'Meow!',
  speak: function () { console.log(this.sound); }
};

cat.speak(); // Output: "Meow!"

var dog = {
  sound: 'Woof!'
};
dog.speak = cat.speak;

dog.speak(); // Output: "Woof!"

var speak = cat.speak;
speak(); // Output: "undefined"

speak = cat.speak.bind(dog);
speak(); // Output: "Woof!"

解释:

"this"的值取决于函数的调用方式。当您将this.alertSomething作为按钮的onClick处理程序时,它会更改它的调用方式,因为您提供了对该函数的直接引用,并且它不会针对对象实例调用(不确定我是否表述正确)。

.bind函数将返回一个新函数,其中"this"被永久设置为传递给它的值。

ECMAScript 5引入了Function.prototype.bind。调用f.bind(someObject)会创建一个具有与f相同的主体和范围的新函数,但是在原始函数中出现this的位置,在新函数中它被永久绑定到bind的第一个参数,无论如何使用该函数。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this

最好在组件的构造函数中执行此操作,以便每个处理程序仅进行一次绑定,而不是在每次呈现时都进行绑定。


1
bind只是核心JavaScript的一部分。它是绑定事件的工作方式,不是React的概念。
下面的文章对此进行了很好的解释。
在JavaScript中,绑定函数是绑定到给定上下文的函数。这意味着无论如何调用它,调用的上下文都将保持不变。
为了将常规函数创建为绑定函数,使用bind方法。bind方法将要绑定函数的上下文作为第一个参数。其余的参数是始终传递给这样的函数的参数。它返回一个绑定函数作为结果。

http://reactkungfu.com/2015/07/why-and-how-to-bind-methods-in-your-react-component-classes/

此外,你应该在构造函数中绑定所有事件,而不是在render方法中绑定。这将防止多次绑定调用。
以下是关于此主题的另一个有用信息。他们说:
我们建议您在构造函数中绑定事件处理程序,以便它们只为每个实例绑定一次。

https://facebook.github.io/react/docs/reusable-components.html


因为当你将类方法传递给React组件或元素时,它们会绑定到这些组件/元素,从而将它们绑定到构造函数中的内部类作用域,将this的值绑定到内部类作用域。 - RegarBoy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接