Kevin K.
Kevin K.

Reputation: 57

How to add arguments to event handler in ES6 React when functions are bound in constructor

With constructors in es6, we are advised to bind functions early, e.g.

class App extends React.Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this); // bound early
  }

  handleClick() {
    // do stuff
  }
  ...
}

In ES5, we could typically call something like this.handleClick.bind(this, "foo") if we wanted to preserve context AND send an extra argument. What is the best pattern for this with the new class syntax in ES6 React?

For instance, if my class looked like the code below, how would I best access the "foo" and "bar" values? (I know the answer is not bind but this is how I could best illustrate the problem).

class App extends React.Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this); // bound early
  }

  handleClick(event, value) {
    // do stuff with value ("foo" or "baz")
  }

  render() {
    return (
      <div>
        <button onClick={this.handleClick.bind("foo")} /> // incorrect code
        <button onClick={this.handleClick.bind("bar")} /> // incorrect code
      </div>
    )
  }
}

Upvotes: 9

Views: 5565

Answers (2)

elclanrs
elclanrs

Reputation: 94121

Think that:

onClick={this.handleClick.bind(this)}

Is the same as:

onClick={e => this.handleClick(e)}

So you can do:

    <button onClick={e => this.handleClick(e, 'foo')} />
    <button onClick={e => this.handleClick(e, 'baz')} />

In the end it is all just JavaScript.

Upvotes: 16

Bergi
Bergi

Reputation: 664787

In ES5, we could typically call something like this.handleClick.bind(this, "foo") if we wanted to preserve context AND send an extra argument.

You can do exactly the same in ES6 as well. It's not like bind was removed from the language :-)

class App extends React.Component {
  constructor(props) {
    super(props);
    this.handleFooClick = this.handleClick.bind(this, "foo"); // bind early
  }

  handleClick(value, event) {
    //        ^^^^^^ notice the bound values come first
    …
  }

  render() {
    return (
      <div>
        <button onClick={this.handleFooClick} /> // use early-bound
        <button onClick={this.handleClick.bind(this, "bar")} /> // bind late
        <button onClick={event => this.handleClick("foobar", event)} /> // arrow function
      </div>
    )
  }
}

Upvotes: 6

Related Questions