0

As far as i know, there are two main pattern of calling inherited method on ReactJS, but I dont know which one should I use, or the best practice,

class ParentCont extends React.Component {
    constructor(props) {
      super(props);
      this.state = {
        myState : "My State"
      }
    }

    callMe() {
      console.log(this.state.myState);
    }

    render() {
      return(
        <div>
          <MyButton myProp={this.callMe.bind(this)} />
        </div>
      )
    }
  }
  class MyButton extends React.Component {
    buttonB() {
      this.props.myProp();
    }
    render() {
      return(
        <div>
          <button onClick={this.props.myProp}>Click Me A</button>
          <button onClick={this.buttonB.bind(this)}>Click Me B</button>
        </div>
      )
    }
  }
  ReactDOM.render(<ParentCont />, document.getElementById('app'));

On above snippet there are two ways of calling the callMe() on ParentCont from MyButton,

First, attaching the props directly to event handler, i.e. Click Me A button,

Second, attaching so called local function to event handler, i.e. Click Me B button,

Which one is the best? or what are the advantages and drawbacks of one another?

xcode
  • 1,637
  • 3
  • 16
  • 25

1 Answers1

1

you want to pass the prop function if you can. It is more efficient and less code to run. The whole point of using a local function that calls the prop function is if you want to use additional information or local information to influence the call on the function. for instance

class MyButton extends React.Component {
    buttonB = () => {
      this.props.myProp(this.props.id);
    }
    render() {
      return(
        <div>
          <button onClick={this.buttonB}>Click Me B</button>
        </div>
      )
    }
  }

or if the child class has a local state for instance you would want to pass it though.

if there is no need to pass variables then you dont need the local function. notice that I removed the bind. you dont want to bind or use an inline arrow function on any handler in the render as it causes a performance hit.

John Ruddell
  • 25,283
  • 6
  • 57
  • 86
  • do you have any reference that stated using bind and inline arrow will cause performance hit? any links maybe? – xcode Apr 12 '17 at 07:17
  • I can look it up for you if you want. or you can just do a google search. The reason why its a performance hit is because both return a new function. this is a new reference to a function as well. Which react will use to re render everything associated with said inline function. you want to use a pre-bound function so its the same function reference – John Ruddell Apr 12 '17 at 07:31
  • If you have the reference why not, as far as i know yes we can ignore using `bind(this)` if the function that we call do not contain any `this` keyword, but we need to use `bind(this)` if we use `this` inside the function, I already tried your snippet but return an error, although you're using arrow function. – xcode Apr 12 '17 at 07:38
  • 1
    thats because you do not have the correct config for babel. you can just add the bind in your constructor to only do it once `this.buttonB = this.buttonB.bind(this)`... [I wrote another answer describing this here](http://stackoverflow.com/a/43331722/2733506) – John Ruddell Apr 12 '17 at 17:32
  • @xcode heres a few links if you really want it. https://medium.com/@esamatti/react-js-pure-render-performance-anti-pattern-fb88c101332f#9bed the eslint standard has adopted this https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-bind.md – John Ruddell Apr 12 '17 at 17:42
  • I think the preferable method for me the one that use `.bind()` inside `constructor` easy to comprehend, thanks – xcode Apr 13 '17 at 07:32
  • But again **if there is no need** to pass additional information and states to the parent, isn't it more convenient to use direct `onClick={this.props.myProp}` (just like `Click Me A` button)? less typing no `bind`-ing needed, so no performance hit right? – xcode Apr 13 '17 at 07:41
  • yes thats exactly what I said in my answer :) you dont want to bind in the render. so either prebind if you need to use a function to handle the event or use a prop function that is passed if you dont need extra info – John Ruddell Apr 13 '17 at 07:59