jsx-no-bind in contextual map function

196 views Asked by At

I have the following code in a render function:

<table className="table table-bordered table-striped">
  <ResultsTableHeader />
  <tbody>
    {results.map(result => (
      <Result
        key={result.get('id')}
        deleteResult={this.props.destroyResult.bind(null, result.get('id'))}
        {...result}
      />
      ))}
  </tbody>
</table>

esling is complaining about react/jsx-no-bind, so normally I would create a reference to the bound func in the constructor but this is different as it is a different function on each call from map.

3

There are 3 answers

0
GG. On BEST ANSWER

The other answers (using =>) are probably incorrect. From the jsx-no-bind documention:

A bind call or arrow function in a JSX prop will create a brand new function on every single render. This is bad for performance, as it will result in the garbage collector being invoked way more than is necessary.

So ESLint will complain with both bind & => (except if you set allowArrowFunctions: true).

The solution is to move the function call inside the component.

In the parent:

<Result
  key={result.get('id')}
  deleteResult={this.props.destroyResult}
  {...result}
/>

In the child:

const Result = (props) => {
  handleDelete = () => props.deleteResult(props.get('id'))
  return (
    <div onClick={handleDelete}></div>
  )
}
0
Jeff McCloud On

You can use the arrow function syntax:

deleteResult={() => this.props.destroyResult(result.get('id'))}
0
Alex Moldovan On

To expand on the answers already given, when you assign an event to a handler, it normally creates a function with its own scope

deleteResult={this.props.destroyResult.bind(null, result.get('id'))}

When you write the assignment as an arrow function, you get the parent scope

deleteResult={() => this.props.destroyResult(result.get('id'))}