1

I'm new to react, don't know how render() works internally. Which one is more efficient and the best practice for event handling in react components?

onNameChange (event) {
  this.setState({ name: event.target.value });
}

render() {
  return (
    <TextField
      value={ this.state.name }
      onChange={ this.onNameChange.bind(this) }
    />
  );
}

OR

render() {
  return (
    <TextField
      value={ this.state.name }
      onChange={ (event) => this.setState({ name: event.target.value }) }
    />
  );
}

And what the case would be if we'd want to do something more than just setting the state with name? e.g. let's say we'd want to split first and last names then set the state:

render() {
  return (
    <TextField
      value={ `${ this.state.name.first } ${ this.state.name.last }` }
      onChange={ (event) => {
        let parts = event.target.value.split(' ');
        this.setState({ name: { first: parts[0], last: parts[1] }}); 
      }}
    />
  );
}
Soheil Jadidian
  • 878
  • 7
  • 12
  • It doesn't really make a difference whether you create a new function by calling `.bind()` or by using an arrow function expression. – Bergi Jun 11 '16 at 20:17
  • 1
    For your 2nd example, a bind call in the render path creates a brand new function on every single render. – nem035 Jun 11 '16 at 20:20
  • Thanks, is there any other way to avoid re-declaring the handler on every render? – Soheil Jadidian Jun 11 '16 at 20:24
  • Possible duplicate of [Calling setState in render is not avoidable](http://stackoverflow.com/questions/35290245/calling-setstate-in-render-is-not-avoidable) – omarjmh Jun 12 '16 at 00:34

1 Answers1

3

The best way to do this is probably to bind the event handler in the constructor instead of binding or using a new arrow function in every render, at least from a perf perspective

constructor() {
  super();
  this.onNameChange = this.onNameChange.bind(this);
}

onNameChange (event) {
 this.setState({ name: event.target.value });
}

render() {
 return (
   <TextField
    value={ this.state.name }
    onChange={ this.onNameChange }
   />
 );
}
Gilad Artzi
  • 3,034
  • 1
  • 15
  • 23
Conor Hastings
  • 490
  • 2
  • 10