Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoiding inline functions in React: How to bind functions with arguments?

I'm trying to follow the no-bind rule for React using the pattern that they have recommended with ES6 classes:

class Foo extends React.Component {
  constructor() {
    super();
    this._onClick = this._onClick.bind(this);
  }
  render() {
    return (
      <div onClick={this._onClick}>
        Hello!
      </div>
    );
  }
  _onClick() {
    // Do whatever you like, referencing "this" as appropriate
  }
}

However, when I need to pass arguments in to _onClick, what needs to change?

I've tried something like:

import {someFunc} from 'some/path';

class Foo extends React.Component {
  constructor() {
    super();
    this._onClick = this._onClick.bind(this, a, b);
  }
  render() {
    const {
     prop1,
     prop2
    } = this.props;

    return (
      <div onClick={this._onClick(prop1, prop2}>
        Hello!
      </div>
    );
  }
  _onClick = (a, b) => {
    someFunc(a, b);
  }
}

However, this does not work. What needs to be altered?

like image 632
TheRealFakeNews Avatar asked Feb 14 '17 16:02

TheRealFakeNews


People also ask

Why not use inline functions in React?

Since two different function instances are never equal, inline functions will cause the shallow equality comparison to fail, and thus will always trigger a re-render. As a result, many React developers encourage you to never use inline functions in render.

How do you avoid the need for binding in React?

To avoid the need for binding we have something introduced in ES6 as arrow functions. Using the arrow function to call this. setState will lead to avoid the use of bind.

Why you shouldn't use inline arrow functions in JSX props?

Using arrow functions or binding in JSX is a bad practice that hurts performance, because the function is recreated on each render. Whenever a function is created, the previous function is garbage collected. Rerendering many elements might create jank in animations.

What is the use of the bind () method in React application?

The bind() is an inbuilt method in React that is used to pass the data as an argument to the function of a class based component.


1 Answers

The call to bind in the constructor should only pass this as a single argument.

this._onClick = this._onClick.bind(this);

Here you are overwriting the property this._onClick with a new one that has the correct this bound. If your function takes two arguments, then you should pass those as normal at call time.

Passing additional arguments to bind means that the function returned already has those arguments supplied - in your attempt the _onClick function will always have its first two arguments undefined, as a and b have no value in the constructor.

Now that you have bound this to your function, you can access this.props from within there, rather than having to pass arguments:

import {someFunc} from 'some/path';

class Foo extends React.Component {
  constructor() {
    super();
    this._onClick = this._onClick.bind(this);
  }
  render() {
    return (
      <div onClick={this._onClick}>
        Hello!
      </div>
    );
  }
  _onClick() {
    const {
     prop1,
     prop2
    } = this.props;
    someFunc(prop1, prop2);
  }
}
like image 89
Tom Fenech Avatar answered Oct 17 '22 16:10

Tom Fenech