反应性能:匿名函数vs命名函数vs方法

时间:2017-03-03 05:06:47

标签: javascript reactjs

我想知道在React.js中,在声明匿名函数,命名函数或组件中的方法之间是否存在性能差异。

具体而言,下列其中一项是否优于其他人?

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}
        />
      );
    }

}

2 个答案:

答案 0 :(得分:7)

是的,肯定是,你的代码的第三个版本是在反应组件的Render块中引用函数的正确方法。

为什么?

通常,嵌套函数被认为是一种反模式,用于被调用超过一次或两次的方法;这主要是因为javascript引擎将函数视为任何其他值,并且必须创建&amp;然后在父母呼叫完成后将其销毁。

如果您需要能够从this内访问handleChange(),则需要将方法绑定到组件的上下文。以下是不会对性能产生任何负面影响的方法。

通过构造函数的Vanilla ES6:

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}
            />
        )
    }
}

Class属性中的箭头函数(需要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}
            />
        )
    }
}

装饰类方法(需要babel w / transform-decorators-legacy和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}
            />
        )
    }
}

希望这有帮助!

答案 1 :(得分:4)

第三种选择是最好的。您希望避免在setState({})函数中设置状态render,因为它不再是纯粹的&#39;。这是人们在谈论functional programming时使用的术语。它基本上意味着没有副作用。即使你在渲染函数中没有立即使用setState调用这些函数,我认为最好将这种逻辑拉到外面并养成思考纯函数的习惯。

  

Pure Functions   纯函数是一个函数:   给定相同的输入,将始终返回相同的输出。   不产生副作用。   不依赖外部可变状态。

另外考虑性能,每次渲染函数运行时都会创建一个新函数。您只需要创建一次这些函数,因此最好将它们拉出来。

渲染功能的运行频率如何?它可以是相当多的!每次更改状态或从父组件传递新道具时。