简体   繁体   中英

What is the best way to write event handler in React?

I had read the article about handle events in react with arrow functions . And the final way in that article is not likely the best because of re-render issue.

eg

 class Example extends React.Component { handleSelect = i => e => { console.log(i) } render() { return {this.state.language.map(item, i) => ( <ListItem ... onPress={this.handleSelect(i)} // re-render sub component every time the Example render() because of the annoymous function /> )} } } 

I wonder which way is the best to write event handler in React?

In order to get the best performance out of React, you need to minimize the number of objects that are being created during renders. And as a reminder a function declaration (eg function myFunc or const func = () => {} ) creates an object.


I would say your code has an unsolvable issue because you're creating a new instance of the inner function when handleSelect is invoked:

handleSelect = i => e => {
  console.log(i)
}

I'll rewrite this using the function notation because it's a bit more clear what happening (but I prefer arrow functions in practice):

handleSelect = function (i) {
  return function (e) {
    console.log(i);
  }
}

The issue here is the with each render when you invoke handleSelect it creates a brand new inner function (ie function (e) {/* ... */} ).


I mentioned that your code has an unsolvable issue because there is no way to split up your curried handleSelect function because you're passing the index i that's created inside the render function . Because that state doesn't exist anywhere else, you have to create a new function to close-over it every time and that's okay.

I would even refactor your code like so:

class Example extends React.Component {
  // as @RickJolly mentioned, this method doesn't have to be arrow
  handleSelect (i) {
    console.log(i)
  }

  render() {
    return {this.state.language.map(item, i) => (
      <ListItem 
        ...
        onPress={() => this.handleSelect(i)}
    )}

  }
}

If you have to create a new function every time, then you might as well inline it vs returning a function. That's preference though.


Edit

As @RickJolly mentioned, if your method doesn't use this then it shouldn't be an arrow function.

From his comment:

since you're calling () => this.handleSelect(i) via an arrow function, this is bound to the this of the enclosing context [which is the class pointer]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM