Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React performance: anonymous function vs named function vs method

I would like to know if, in React.js, there is a performance difference between declaring an anonymous function, a named function, or a method within a component.

Concretely, is one of the following more performant than the others?

class MyComponent extends React.Component {
  render() {
    return (
      <input
        type="text"
        value={foo}
        onChange={(e) => {
          this.setState({ foo: e.target.value });
        }}
      />
    );
  }
}

class MyComponent extends React.Component {
  ...
  render() {
    function handleChange(e) {
      this.setState({ foo: e.target.value });
    }
    return (
      <input
        type="text"
        value={foo}
        onChange={handleChange}
      />
    );
  }
}

class MyComponent extends React.Component {
    ...
    handleChange(e) {
      this.setState({ foo: e.target.value });
    }

    render() {
      return (
        <input
          type="text"
          value={foo}
          onChange={this.handleChange}
        />
      );
    }

}
like image 275
Sung Cho Avatar asked Mar 03 '17 05:03

Sung Cho


1 Answers

Yes there most certainly is, The third version of you're code is the correct way of referencing a function within the Render block of a react component.

Why?

Generally nesting functions is considered an anti-pattern for methods that will be called more than once or twice; This is due primarily to the fact the javascript engine sees functions as any other value and must create & then subsequently destroy it after the parent call has completed.

If you need to be able to access this from within handleChange() you need to bind the method to the context of the component. The following are the methods that would not result in any negative performance impact.

Vanilla ES6 via constructor:

class MyComponent extends React.Component {
    constructor(props) {
        super(props)
        this.handleChange = this.handleChange.bind(this)
    }

    handleChange(e) {
        this.setState({ foo: e.target.value });
    }

    render() {
        return (
            <input
                type="text"
                value={foo}
                onChange={this.handleChange}
            />
        )
    }
}

Arrow function in Class Property (requires babel w/ transform-class-properties):

class MyComponent extends React.Component {
    handleChange = (e) => {
        this.setState({ foo: e.target.value });
    }

    render() {
        return (
            <input
                type="text"
                value={foo}
                onChange={this.handleChange}
            />
        )
    }
}

Decorated Class method (requires babel w/ transform-decorators-legacy and core-decorators):

import { autobind } from 'core-decorators'

class MyComponent extends React.Component {

    @autobind
    handleChange(e) {
        this.setState({ foo: e.target.value });
    }

    render() {
        return (
            <input
                type="text"
                value={foo}
                onChange={this.handleChange}
            />
        )
    }
}

Hope this helps!

like image 157
Luigi Poole Avatar answered Oct 08 '22 12:10

Luigi Poole