React.createClass与React.Component区别
根据上面展示代码中二者定义组件的语法格式不同之外,二者还有很多重要的区别,下面就描述一下二者的主要区别。
(1)函数this自绑定
React.createClass
创建的组件,其每一个成员函数的this都有React自动绑定,任何时候使用,直接使用this.method
即可,函数中的this
会被正确设置。
const Contacts = React.createClass({ handleClick() { console.log(this); // React Component instance }, render() { return ( <div onClick={this.handleClick}></div> ); } });
React.Component
创建的组件,其成员函数不会自动绑定this,需要开发者手动绑定,否则this不能获取当前组件实例对象。
class Contacts extends React.Component { constructor(props) { super(props); } handleClick() { console.log(this); // null } render() { return ( <div onClick={this.handleClick}></div> ); }
当然,React.Component
有三种手动绑定方法:可以在构造函数中完成绑定,也可以在调用时使用method.bind(this)
来完成绑定,还可以使用arrow function来绑定。拿上例的handleClick
函数来说,详见React.Component三种手动绑定this方法.
(2)组件属性类型propTypes及其默认props属性defaultProps配置不同
React.createClass
在创建组件时,有关组件props的属性类型及组件默认的属性会作为组件实例的属性来配置,其中defaultProps是使用getDefaultProps
的方法来获取默认组件属性的
const TodoItem = React.createClass({ propTypes: { // as an object name: React.PropTypes.string }, getDefaultProps(){ // return a object return { name: '' } } render(){ return <div></div> } })
React.Component
在创建组件时配置这两个对应信息时,他们是作为组件类的属性,不是组件实例的属性,也就是所谓的类的静态属性来配置的。对应上面配置如下:
class TodoItem extends React.Component { static propTypes = {//类的静态属性 name: React.PropTypes.string }; static defaultProps = {//类的静态属性 name: '' }; ... }
(3)组件初始状态state的配置不同
React.createClass
创建的组件,其状态state是通过getInitialState
方法来配置组件相关的状态; React.Component
创建的组件,其状态state是在constructor
中像初始化组件属性一样声明的。
const TodoItem = React.createClass({ // return an object getInitialState(){ return { isEditing: false } } render(){ return <div></div> } }) class TodoItem extends React.Component{ constructor(props){ super(props); this.state = { // define this.state in constructor isEditing: false } } render(){ return <div></div> } }
(4)Mixins的支持不同
Mixins
(混入)是面向对象编程OOP的一种实现,其作用是为了复用共有的代码,将共有的代码通过抽取为一个对象,然后通过Mixins
进该对象来达到代码复用。具体可以参考React Mixin的前世今生。
React.createClass
在创建组件时可以使用mixins
属性,以数组的形式来混合类的集合。
var SomeMixin = { doSomething() { } }; const Contacts = React.createClass({ mixins: [SomeMixin], handleClick() { this.doSomething(); // use mixin }, render() { return ( <div onClick={this.handleClick}></div> ); } });
但是遗憾的是React.Component
这种形式并不支持Mixins
,至今React团队还没有给出一个该形式下的官方解决方案;但是React开发者社区提供一个全新的方式来取代Mixins
,那就是Higher-Order Components,具体细节可以参考这篇文章
(5)取舍
由于React团队已经声明React.createClass最终会被React.Component的类形式所取代。但是在找到Mixins
替代方案之前是不会废弃掉React.createClass
形式。所以:
能用React.Component创建的组件的就尽量不用React.createClass形式创建组件。
除此之外,创建组件的形式选择还应该根据下面来决定:
1、只要有可能,尽量使用无状态组件创建形式。 2、否则(如需要state、生命周期方法等),使用`React.Component`这种es6形式创建组件
补充一点
无状态组件内部其实是可以使用
ref
功能的,虽然不能通过this.refs
访问到,但是可以通过将ref内容保存到无状态组件内部的一个本地变量中获取到。
例如下面这段代码可以使用ref来获取组件挂载到dom中后所指向的dom元素:
function TestComp(props){ let ref; return (<div> <div ref={(node) => ref = node}> ... </div> </div>) }
.