How To Handle Events in React - Different Way vs Best Way?
In the Facebook docs, you’ll see event handling done like this:
There’s a much cleaner way to write event handlers that
1) avoids boilerplate and
2) doesn’t cause extra re-renders:
It’s a fancy name, but the idea is really simple… just use arrow functions to define your event handlers. Like this:
{
// "this"
}
handleInput = (e) => {
// "this", "e"
}
handleRemove = (id) => (e) => {
// "this", "e", "id"
}
}
You can pass arguments without using bind in your render methods, or your constructor! Everything looks really spick and span.
// option 1 class Thing extends React.Component { constructor() { this.handleSmthng = this.handleSmthng.bind(this) } render() { <input onChange={this.handleSmthng}/> } handleSmthng(e) { // ... } }ES6 classes won’t automatically give
this
scope to handleSmthng
, and since you’ll usually want to call this.setState
or perhaps invoke another method in the component, the “official” convention is to bind all the event handlers all the time in constructor. This works, but can quickly feel like boilerplate code.
// option 2 class Thing extends React.Component { render() { <button onClick={() => this.handleSmthng('foo')}> ADD </button> } handleSmthng(arg1) { // ... } }It will pass
this
context to handleSmthng
and it avoids boilerplate code in the constructor
. Heck, there’s no state in this component so you don’t even need a constructor
! I think the motivations for this approach are right… but there’s a slight performance cost. Using an arrow function will always create a new reference in JavaScript which, in turn, increases memory usage for your apps. While memory is cheap in JavaScript, renders are costly in React. When you pass arrow functions to child components, your child component will indiscriminately re-render since (as far as it’s concerned) that arrow function is new data. There’s a much cleaner way to write event handlers that
1) avoids boilerplate and
2) doesn’t cause extra re-renders:
property initializer syntax
!It’s a fancy name, but the idea is really simple… just use arrow functions to define your event handlers. Like this:
class TodoApp extends React.Component { render() { return ( <div> <button onClick={this.handleClick}> ADD </button> <input onChange={this.handleInput}/> </div> ); } handleClick = () => { // "this" } handleInput = (e) => { // "this", "e" } }You defined two handlers, and it’s looking really nice. No boilerplate. Easy to read. Easy to re-factor… if you want to pass arguments:
class TodoApp extends React.Component { render() { return ( <div> <button onClick={this.handleClick}> ADD </button> <input onChange={this.handleInput}/> { this.state.todos.map((item) => { return ( <li onClick={this.handleRemove(item.id)}> {item.text} </li> ); }); }
Source: A New Way to Handle Events in React
Comments
Post a Comment