React如何绑定一个函数到一个组件实例?

389 阅读1分钟

有以下几种方式可以确保函数可以访问组件属性,比如像this.props和this.state,取决于使用的语法和构建步骤。

  1. 在构造函数中绑定(ES2015)
class Foo extends Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }
  handleClick() {
    console.log('Click happened');
  }
  render() {
    return <button onClick={this.handleClick}>Click Me</button>;
  }
}
  1. 类属性(第三阶段提案)
class Foo extends Component {
  // Note: this syntax is experimental and not standardized yet.
  handleClick = () => {
    console.log('Click happened');
  }
  render() {
    return <button onClick={this.handleClick}>Click Me</button>;
  }
}
  1. 在Render中的绑定
class Foo extends Component {
  handleClick() {
    console.log('Click happened');
  }
  render() {
    return <button onClick={this.handleClick.bind(this)}>Click Me</button>;
  }
}

注意:在render方法中使用Function.prototype.bind会在每次组件渲染时创建一个新的函数,可能会影响性能。

  1. 在Render中的箭头函数
class Foo extends Component {
  handleClick() {
    console.log('Click happened');
  }
  render() {
    return <button onClick={() => this.handleClick()}>Click Me</button>;
  }
}

注意:在render方法中使用箭头函数也会在每次组件渲染时创建一个新的函数,可能会影响性能。

如何传递参数给事件处理器或回调?

  1. 可以使用箭头函数包裹事件处理器,并传递参数:
<button onClick={() => this.handleClick(id)} />
  1. 以上代码和调用.bind是等价的:
<button onClick={this.handleClick.bind(this, id)} />
  1. 通过data-属性传递参数
const A = 65 // ASCII character code

class Alphabet extends React.Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
    this.state = {
      justClicked: null,
      letters: Array.from({length: 26}, (_, i) => String.fromCharCode(A + i))
    };
  }

  handleClick(e) {
    this.setState({
      justClicked: e.target.dataset.letter
    });
  }

  render() {
    return (
      <div>
        Just clicked: {this.state.justClicked}
        <ul>
          {this.state.letters.map(letter =>
            <li key={letter} data-letter={letter} onClick={this.handleClick}>
              {letter}
            </li>
          )}
        </ul>
      </div>
    )
  }
}