React.createClass 对比 extends React.Component

今天在写代码的时候,突然想到这个问题,于是找了一篇文章,文章地址:https://toddmotto.com/react-create-class-versus-component/
以下是翻译,如果有不对的地方,欢迎指正。

大多数情况下,可以认为是实现同一个功能的两种方法。React提供了React.createClass方法来创建组件类, 并发布了一个语法糖更新,通过扩展React.Component类而不是调用createClass的方法, 更好地使用ES6模块。

    1. 1.语法区别
    2. 2.propTypes and getDefaultProps
    3. 3.State区别
    4. 4.“this”的区别
    5. 5.Mixins
    6. 6.建议

这些差异在各个地方都很微妙,有许多值得探讨的差异,了解这些差异,帮助你做出最适合决策。

语法区别

首先,我们通过查看两个代码示例,对它们进行注释来研究语法差异。

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。 这是一个重要的改变,要注意这个语法变化带来的进一步变化。

propTypes and getDefaultProps

让我们来看看, 如何使用和声明default props,以及它们的类型和设置初始状态的重要变化。

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。

import React from 'react';
class Contacts extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (
      <div></div>
    );
  }
}
Contacts.propTypes = {
};
Contacts.defaultProps = {
};
export default Contacts;

 

State区别

状态的变化很有趣,我们使用构造函数实现初始状态更改。
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;

 

“this”的区别

使用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;

 

Mixins

使用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类 。 现在,它们都只是语法不同的语义,它们做同样的事情 - 它们都是类!

 

转载于:https://www.cnblogs.com/jhonyoung/p/8890872.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值