【问题标题】:Is functional component with arrow function handler better for performance then a class component with a handler bound in constructor?具有箭头函数处理程序的功能组件是否比具有绑定在构造函数中的处理程序的类组件的性能更好?
【发布时间】:2017-10-03 14:05:59
【问题描述】:

我有一个带有箭头函数事件处理程序的功能组件,这被认为是不好的做法,因为每次渲染组件时都需要重新创建函数。

const SimpleQuestion = ({
  question,
  onChangeQuestionTitle
}) => {

  return (
    <div>
      <input
        type="text"
        placeholder="Enter Question"
        value={question.title}
        onChange={(e) => onChangeQuestionTitle({
          id: question.id,
          title: e.target.value
        })}
      />
    </div>
  );
};

我不能为它定义外部函数,因为它需要访问道具,我也看不出这个例子有什么好处:

const SimpleQuestion = ({
  question,
  onChangeQuestionTitle
}) => {

  const handleChangeQuestionTitle = (e) => {
    onChangeQuestionTitle({
      id: question.id,
      title: e.target.value
    });
  };

  return (
    <div>
      <input
        type="text"
        placeholder="Enter Question"
        value={question.title}
        onChange={handleChangeQuestionTitle}
      />
    </div>
  );
};

为了消除对箭头函数的需要,我可以使用带有构造函数和 bind() 的类组件。例如:

class SimpleQuestion extends React.Component {
  constructor(...args) {
    super(...args)  
    this.onChangeQuestionTitle = this.onChangeQuestionTitle.bind(this);
  }

  render() {
    return (
      <div>
        <input
          type="text"
          placeholder="Enter Question"
          value={question.title}
          onChange={this.onChangeQuestionTitle}
        />
      </div>
    );
  }

  onChangeQuestionTitle(e) {
    this.props.onChangeQuestionTitle({
      id: question.id,
      title: e.target.value
    });
  }
}

我应该使用类组件还是带有箭头功能的函数组件?从性能角度来看,哪个更好?

PS:我知道我可以从 Question 组件中导出逻辑并在父容器中执行处理程序逻辑,但这个问题与性能主题有关。

谢谢

【问题讨论】:

标签: javascript reactjs


【解决方案1】:

因为您只需要返回一些 jsx 而您不关心组件的状态或任何生命周期方法,因此最好的选择是 #2。

关于通过将函数的引用传递给render() 方法而不是函数本身的方法来创建不必要的匿名函数的问题将得到解决。

【讨论】:

  • 我认为 #2 和 #1 初始化处理函数的次数相同。唯一不同的是,#2 中的 handler 是在 JSX 之外定义的,但由于组件本身是一个纯函数,所以每次都会调用它,需要重新渲染。同意 #3 示例具有状态和生命周期,并且会降低性能。那就是问题出现了,我应该使用类组件而不重新初始化处理程序函数,还是使用功能组件重新初始化?从性能的角度来看,女巫一号是更有效的解决方案?
  • 在这种情况下,最好的选择是第二种,它会渲染得更快,你不需要基于类的组件,因为你不关心工作的组件的状态父组件,并且因为您只返回 JSX 功能组件是最好的选择。
【解决方案2】:

首选第二种或第三种方法。至于你应该选择哪个,我认为这是个人喜好。我个人更喜欢粗箭头语法(#2),因为您不必在构造函数中绑定。但无论哪种情况,您都可以通过将函数的引用(而不是函数定义)传递给 render() 来解决创建不必要的匿名函数的问题。

【讨论】:

  • 正如前面的答案评论中已经提到的,我会说第二个创建数组函数的次数与第一个示例相同,因为组件本身是每次需要重新渲染时调用的纯函数。问题是 - 我应该使用具有状态和生命周期的类组件(这会降低性能),还是应该在每次重新渲染组件时坚持使用功能组件和处理程序函数重新初始化?哪个变体性能更好,为什么?
  • 我认为第二个与第一个相同是错误的,但如果您有参考,请随时证明我错了。明天我会尝试找到支持我的主张的东西
  • zsoltnagy.eu/… "带有回调的组件呢?"说“这种方法的唯一问题是每次渲染 DOM 时都会重新创建处理函数。”
  • 是的,我认为那篇文章也是错误的。如果您通读Handling Events - Official React Docs,您会发现他们提出了三种绑定处理程序的方法。他们唯一警告的是内联粗箭头&lt;button onClick={(e) =&gt; this.handleClick(e)}&gt;,警告是“这种语法的问题是每次 LoggingButton 呈现时都会创建不同的回调”
  • 您源代码中的第一个和第二个示例处理类组件,而不是像我的示例中那样的功能组件。因此,您可以使用构造函数中的绑定或类字段语法来定义类中的字段。当使用类组件时,仅在重新渲染期间调用 render 方法,而不是像功能组件那样调用整个函数。
猜你喜欢
  • 1970-01-01
  • 2016-08-23
  • 2016-09-06
  • 2016-12-04
  • 2014-03-17
  • 2020-03-24
  • 1970-01-01
  • 1970-01-01
  • 2023-01-27
相关资源
最近更新 更多