在React中避免使用内联函数:如何使用参数绑定函数?

时间:2017-02-14 16:47:47

标签: javascript reactjs ecmascript-6 bind

我尝试使用他们推荐的ES6类模式来遵循React的no-bind规则:

class Foo extends React.Component {
  constructor() {
    super();
    this._onClick = this._onClick.bind(this);
  }
  render() {
    return (
      <div onClick={this._onClick}>
        Hello!
      </div>
    );
  }
  _onClick() {
    // Do whatever you like, referencing "this" as appropriate
  }
}

但是,当我需要将参数传递给_onClick时,需要改变什么?

我尝试过类似的事情:

import {someFunc} from 'some/path';

class Foo extends React.Component {
  constructor() {
    super();
    this._onClick = this._onClick.bind(this, a, b);
  }
  render() {
    const {
     prop1,
     prop2
    } = this.props;

    return (
      <div onClick={this._onClick(prop1, prop2}>
        Hello!
      </div>
    );
  }
  _onClick = (a, b) => {
    someFunc(a, b);
  }
}

然而,这不起作用。需要改变什么?

4 个答案:

答案 0 :(得分:7)

构造函数中对bind的调用只应将this作为单个参数传递。

this._onClick = this._onClick.bind(this);

在这里,您将使用具有正确this._onClick范围的新属性覆盖属性this。如果你的函数有两个参数,那么你应该在调用时正常传递它们。

将附加参数传递给bind意味着返回的函数已经提供了这些参数 - 在您的尝试中,_onClick函数将始终具有其前两个参数undefined,作为{{1 }和a在构造函数中没有值。

现在您已将b绑定到您的函数,您可以从那里访问this,而不必传递参数:

this.props

答案 1 :(得分:4)

您应该使用partial application。基本上你用你想要的参数初始化你的onClick函数,onClick函数将返回一个新的函数,当点击div时调用它。

import {someFunc} from 'some/path';

class Foo extends React.Component {
  render() {
    return (
      <div onClick={this._onClick(prop1, prop2}>
        Hello!
      </div>
    );
  }
  _onClick = (a, b) => {
    return () => someFunc(a, b);
  }
}

PS:这仅适用于您的参数ab不属于this.props的情况,如果它们是您应该按照Tom Fenech说的那样做。

答案 2 :(得分:1)

另一种方法是使用Babel stage 1 autobind并跳过构造函数。

import {someFunc} from 'some/path';

class Foo extends React.Component {
  _onClick = () => {
    const {
     prop1,
     prop2
    } = this.props;
    someFunc(prop1, prop2);
  }

  render() {
    return (
      <div onClick={this._onClick}>
        Hello!
      </div>
    );
  }
}

答案 3 :(得分:0)

要回答您的问题,为了将参数传递给this._onClick函数,您无需做任何特别的事情。

正确的修订代码将是:

class Foo extends React.Component {
  constructor() {
    super();
    this._onClick = this._onClick.bind(this);
  }
  render() {
    return (
      <div onClick={() => this._onClick(1, 2)}>
        Hello!
      </div>
    );
  }
  _onClick = (a, b) => {
    console.log(a, b);
  }
}

其次,您调用this._onClick的方式不是在click上调用函数的正确方法。

现在正在发生的事情是,在每个渲染过程中,您的函数被调用,因为您没有将该函数作为参数传递,而是调用该函数并将其返回值分配给onClick prop。

你必须这样做:

render() {
  return (
    <div onClick={() => this._onClick(prop1, prop2)}>
      Hello!
    </div>
  );
}

通过以这种方式调用您的函数,您可以确保在发生单击事件时调用this._onClick