React.createClass vs. ES6 箭头函数

Posted

技术标签:

【中文标题】React.createClass vs. ES6 箭头函数【英文标题】:React.createClass vs. ES6 arrow function 【发布时间】:2016-09-07 08:05:34 【问题描述】:

我是 React 新手,正在尝试掌握语法。

我在 React 15 环境中开发(使用 react-starterify 模板)并且一直使用下面版本 2 中的语法,但是,我在 Facebook 的 React 页面中找到的大多数示例和教程都是版本 1。两者之间的区别以及何时应该使用一个而不是另一个?

版本 1

var MyComponent = React.createClass(
  render: function() 
    return (
      <ul>
        // some list
      </ul>
    );
  
);

module.exports = MyOtherComponent;

第 2 版

const MyComponent = () => (
  <ul>
    // some list
  </ul>
);

export default MyComponent;

【问题讨论】:

第一个版本允许你挂钩到诸如componenDidMountshouldComponentUpdate 等生命周期方法。第二个版本基本上只是render 函数。默认使用版本 2,如果需要生命周期方法,请使用版本 1。 还要注意createClass是旧的类风格,现在你可以(应该)使用ES6 classes。 在 react native 中也弃用了 createClass。 【参考方案1】:

第二个代码是一个无状态功能组件,它是一种新的语法/模式,用于将组件定义为props 的函数。它是在 React v0.14 中引入的。

您可以在 React 官方博客 here 上阅读更多相关信息,在 React 官方文档 here 上阅读。

这些组件的行为就像一个只有一个渲染的 React 类 方法定义。由于没有为 a 创建组件实例 功能组件,任何添加到一个的 ref 都将评估为 null。 功能组件没有生命周期方法,但可以设置 .propTypes.defaultProps 作为函数的属性。

此模式旨在鼓励创建这些简单的 应该包含大部分应用程序的组件。在里面 未来,我们还将能够进行具体的性能优化 通过避免不必要的检查和记忆来连接这些组件 分配。


有什么区别?

这种模式类似于“传统”模式,不同之处在于您使用的是简单函数而不是类中定义的方法。当您想从类中提取函数时(例如为了可读性和清洁性),这可能很有用。

需要注意的重要一点是,功能组件就是这样 - 函数。这不是一堂课。因此,没有全局 this 对象。这意味着当您执行render 时,您基本上是在创建ReactComponent 的新实例,从而排除了这些javascript 对象通过一些全局this 相互通信的可能性。这也导致无法使用state 和任何生命周期方法。


我的应用如何从中受益?

性能 当您使用无状态功能组件时,React 足够聪明,可以省略所有“传统”生命周期方法,结果证明提供了相当多的优化。 React 团队表示,他们计划在未来对内存分配进行进一步优化,并减少检查次数。

适应性 因为我们只讨论一个函数(而不是一个类),所以我们不需要担心state、生命周期方法或其他依赖项。给定参数,函数将始终给出相同的输出。因此,我们可以很容易地在任何我们想要的地方调整这些组件,这也使测试变得更容易。

使用 React 的无状态功能组件,可以轻松地单独测试每个组件。不需要模拟、状态操作、特殊库或棘手的测试工具。

鼓励最佳做法 React 经常被比作 MVC 模式的 V,因为它是用来创建视图的。创建组件的“传统”方法可以轻松地将业务逻辑(例如使用stateref)“侵入”到真正应该只处理渲染逻辑的组件中。他们鼓励懒惰和编写臭代码。然而,无状态功能组件几乎不可能采取这种捷径并强制采用更好的方法。


我应该什么时候使用一个而不是另一个?

一般来说,建议尽可能使用新模式!如果您只需要 render 方法,但不需要生命周期方法或 state,请使用此模式。当然,有时您确实需要使用state,在这种情况下,您可以使用传统模式。

Facebook 建议在渲染静态展示组件时使用无状态组件。然后,如果需要某种状态,只需将它们包装在有状态组件中,通过使用其'state 并将props 发送到无状态组件来管理它们。

【讨论】:

感谢您的详尽回答。我使用 Granze 的 react-starterify git 作为我的起点,它专门将 const 用于框架......但对于动态 webapp 来说,访问状态和生命周期似乎对很多事情都至关重要,不?我确实注意到 App.js 文件中有一个“App.propTypes = children: React.PropTypes.object 。也许这是为了存储跨组件数据? 我没有用react-starterify 说,但是你所指的代码sn-p 很可能只是一个类型声明。也许对react-starterify 有经验的人可以提供一些启示。【参考方案2】:

要添加,从 react 15.5.0 开始,React.createClass 将被弃用。他们建议您转到 ES2015 课程或使用箭头功能。

当 React 最初发布时,没有在 JavaScript 中创建类的惯用方法,因此我们提供了自己的:React.createClass。

后来,类作为 ES2015 的一部分被添加到该语言中,因此我们添加了使用 JavaScript 类创建 React 组件的能力。除了函数式组件,JavaScript 类现在是在 React 中创建组件的首选方式。

对于您现有的 createClass 组件,我们建议您将它们迁移到 JavaScript 类。

【讨论】:

以上是关于React.createClass vs. ES6 箭头函数的主要内容,如果未能解决你的问题,请参考以下文章

报错 _react3.default.createClass is not a function

React 中的 ComponentPureComponent无状态组件 之间的比较

React基础知识

将 React 组件从函数重构为 ES6 类

如何在 react.js ES6 中使用道具设置状态

React & Redux 的一些基本知识点