今天在写代码的时候,忽然想到这个问题,因而找了一篇文章,文章地址:https://toddmotto.com/react-create-class-versus-component/
如下是翻译,若是有不对的地方,欢迎指正。react
大多数状况下,能够认为是实现同一个功能的两种方法。React提供了React.createClass方法来建立组件类, 并发布了一个语法糖更新,经过扩展React.Component类而不是调用createClass的方法, 更好地使用ES6模块。api
这些差别在各个地方都很微妙,有许多值得探讨的差别,了解这些差别,帮助你作出最适合决策。数组
首先,咱们经过查看两个代码示例,对它们进行注释来研究语法差别。浏览器
React.createClass
在这里咱们指定React类的变量Contacts , 运用render函数来完成一个典型的基础组件定义。并发
import React from 'react'; const Contacts = React.createClass({ render() { return ( <div></div> ); } }); export default Contacts;
React.Component
参考上面的代码,用ES6 的 class 实现一个相同的组件。函数
import React from 'react'; class Contacts extends React.Component { constructor(props) { super(props); } render() { return ( <div></div> ); } } export default Contacts;
从JavaScript的角度来看,咱们如今使用的是ES6类,一般这会与Babel之类的一块儿使用,将ES6编译为ES5在浏览器中工做。 经过上面的写法,用到了constructor,须要调用super()将props传递给React.Component。
对于React更改,咱们从React.Component扩展获得一个名为“Contacts”的类, 而不是直接调用React.createClass,减小了的React模板的使用,更多的用到了JavaScript。 这是一个重要的改变,要注意这个语法变化带来的进一步变化。this
让咱们来看看, 如何使用和声明default props,以及它们的类型和设置初始状态的重要变化。spa
React.createClass
在React.createClass中,propTypes属性是一个Object,咱们能够在其中声明每一个prop的类型。 getDefaultProps属性是一个返回Object来建立初始props的函数。翻译
import React from 'react'; const Contacts = React.createClass({ propTypes: { }, getDefaultProps() { return { }; }, render() { return ( <div></div> ); } }); export default Contacts;
React.Component
这将propTypes用做实际Contacts类的属性,而不是做为createClass定义Object的的属性。 我认为建立类属性是更好的语法,本身定义类属性,比用react 的 api 更加清晰。
getDefaultProps如今已经变成了名为defaultProps的Object类属性,它再也不是“get”函数,它只是一个Object。 我喜欢这种语法,由于它避免了更多的React模板,只是普通的JavaScript。code
import React from 'react'; class Contacts extends React.Component { constructor(props) { super(props); } render() { return ( <div></div> ); } } Contacts.propTypes = { }; Contacts.defaultProps = { }; export default Contacts;
状态的变化颇有趣,咱们使用构造函数实现初始状态更改。
React.createClass
这里有一个getInitialState函数,它只是返回一个初始状态的对象。
import React from 'react'; const Contacts = React.createClass({ getInitialState () { return { }; }, render() { return ( <div></div> ); } }); export default Contacts;
React.conponent
getInitialState函数已经废弃,咱们将全部状态声明为构造函数中的一个简单的初始化属性,这更像JavaScript,更少的“API”驱动。
import React from 'react'; class Contacts extends React.Component { constructor(props) { super(props); this.state = { }; } render() { return ( <div></div> ); } } export default Contacts;
使用React.createClass会自动绑定this的值到组件上,但使用ES6类时不会自动绑定。
React.createClass
带有this.handleClick绑定的onClick声明。 当这个方法被调用时,React会将正确的执行上下文应用于handleClick。
import React from 'react'; const Contacts = React.createClass({ handleClick() { console.log(this); // React Component instance }, render() { return ( <div onClick={this.handleClick}></div> ); } }); export default Contacts;
React.Component
对于ES6类,类的属性不会自动绑定到React类实例。
import React from 'react'; class Contacts extends React.Component { constructor(props) { super(props); } handleClick() { console.log(this); // null } render() { return ( <div onClick={this.handleClick}></div> ); } } export default Contacts;
有几种方法能够绑定正确的上下文,如下是如何绑定内联:
import React from 'react'; class Contacts extends React.Component { constructor(props) { super(props); } handleClick() { console.log(this); // React Component instance } render() { return ( <div onClick={this.handleClick.bind(this)}></div> ); } } export default Contacts;
或者,能够在构造函数内部更改this.handleClick的上下文以免内联重复,用这种方法避免修改JSX,是更好的方法:
import React from 'react'; class Contacts extends React.Component { constructor(props) { super(props); this.handleClick = this.handleClick.bind(this); } handleClick() { console.log(this); // React Component instance } render() { return ( <div onClick={this.handleClick}></div> ); } } export default Contacts;
使用ES6中编写的React组件时,再也不支持React mixins。
React.createClass
使用React.createClass,咱们可使用mixins属性将mixin添加到组件,该属性须要一个可用的mixin数组。 而后这些扩展组件类。
import React from 'react'; var SomeMixin = { doSomething() { } }; const Contacts = React.createClass({ mixins: [SomeMixin], handleClick() { this.doSomething(); // use mixin }, render() { return ( <div onClick={this.handleClick}></div> ); } }); export default Contacts;
React.Component
不支持
Facebook确实建议未来完全删除React.createClass以支持ES6类 。 如今,它们都只是语法不一样的语义,它们作一样的事情 - 它们都是类!