Kamil W
Kamil W

Reputation: 2366

React - Arrow function vs bind() and event with argument

I'm a newbie in react (even in JS). I'm made the following code in my App class:

nameChangeHandler = (event, personId) => {
//method code
};

render()
{
  <div>
    {this.state.persons.map((person, index) => {
      return <Person
          // nameChangeHandler={(event) => this.nameChangeHandler(event, person.id)}
          nameChangeHandler={this.nameChangeHandler.bind(this, person.id)}
      />
    })}
  </div>
}

I'm passing nameChangeHandler to Person component where I call it in onChange event in input tag (<input type="text" onChange={props.nameChangeHandler}/>)

Application works fine when I pass it in this way:
nameChangeHandler={(event) => this.nameChangeHandler(event, person.id)}
but it doesn't when I do it like this:
nameChangeHandler={this.nameChangeHandler.bind(this, person.id)}

It fails with an exception when I'm trying to acces event.target.value in nameChangeHandler method.

How can I pass event and argument to this method using bind() method instead of arrow function?

I've heard we should always use bind() approach over the arrow function because an arrow function approach could render component many times.

Is there any special use cases and differences between bind() and arrows functions?

Upvotes: 2

Views: 581

Answers (1)

Quentin
Quentin

Reputation: 943527

It's a matter of timing.

When you use bind, the arguments map on to the function you are binding in the order you bind them followed by any that are passed to the new function.

When you use an arrow function, you are explicitly passing them in the order you determine.

Your function expects event to be the first argument, so when you use an arrow you function you pass event, person.id. However, when you bind you pass person.id (the first argument) and when the function is called with event you pass that (as the second argument).

This means you arguments end up the wrong way around.

Since you only have person.id when you call bind and you don't get event until later, the only way you can use bind for this is to change the original function so it accepts the arguments in a different order.

nameChangeHandler = (personId, event) => {

Upvotes: 5

Related Questions