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;
【问题讨论】:
第一个版本允许你挂钩到诸如componenDidMount
、shouldComponentUpdate
等生命周期方法。第二个版本基本上只是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,因为它是用来创建视图的。创建组件的“传统”方法可以轻松地将业务逻辑(例如使用state
或ref
)“侵入”到真正应该只处理渲染逻辑的组件中。他们鼓励懒惰和编写臭代码。然而,无状态功能组件几乎不可能采取这种捷径并强制采用更好的方法。
我应该什么时候使用一个而不是另一个?
一般来说,建议尽可能使用新模式!如果您只需要 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