React.createClass 对决 extends React.Component
来源:互联网 发布:mac maven 使用教程 编辑:程序博客网 时间:2024/05/17 08:16
先给出结论,其实这是创建类的两种殊途同归方式。过去我们一般都会使用 React.createClass 方法来创建组件,但基于 ES6 的语法糖,我们还可以通过 extends React.Component 来创建组件。
这两种创建方式之间的差别很小,只有了解了两者之间的趣味区别,我们才能做出最适合自己的选择。
语法区别
首先,让我们通过两个代码片段来看看两者到底有哪些语法区别。
React.createClass
我们先赋一个常量给新建的class,也加上 render 函数来定义完成最基本的组件。
import React from 'react';const Contacts = React.createClass({ render() { return ( <div></div> ); }});export default Contacts;
React.Component
接下来把 React.createClass 定义的部分转换成 ES6 代码。
import React from 'react';class Contacts extends React.Component { constructor(props) { super(props); } render() { return ( <div></div> ); }}export default Contacts;
从 JavaScript 语言层面来看,我们已经在使用 ES6 中的类了,通常这些 ES6 代码需要使用类似 Babel 的工具转换为 ES5 代码之后才能在浏览器中正常执行。这里我们引入了一个叫 constructor 的属性,因为我们需要在此调用 super() 函数给 React.Component 传递属性。
在这次代码转换中,我们通过继承 React.Component 代替直接调用 React.createClass 的方式,创建了一个叫做“Contacts”的类,增加了这段代码的 JavaScript味道 。在整个语法转换的过程中,这一步具有革命性的意义。
propType 和 getDefaultProps
这个关乎如何使用、声明默认属性和类型,以及如何设置给类初始化状态的重要变化。
React.createClass
在调用 React.createClass 时,我们添加了一个叫做 propTypes 的对象,只要给它的属性进行赋值就能声明对应属性的类型。 getDefaultProps 这个函数返回了一个对象,这个对象的所有属性将会作为组件的初始化属性。
iimport React from 'react';const Contacts = React.createClass({ propTypes: { }, getDefaultProps() { return { }; }, render() { return ( <div></div> ); }});export default Contacts;
React.Component
转换语法之后,我们通过给 Contacts 类添加一个名为 propTypes 属性的方式来达到和上面同样的效果。我认为这种方式比之前更加简洁了。
而 getDefaultProps 函数也变成了一个名为 defaultProps 的属性,注意它仅仅是一个对象而不是“get”函数。我更喜欢这种语法,因为它跳出了 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.Component
转换以后 getInitialState 函数被抛弃了,我们在 constructor 中像创建初始化属性一样声明了所有状态,我认为这样更加像 JavaScript 并且更少地驱动了相应函数。
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 时 React 会自动帮我们处理函数中的 this 指针,但使用 ES6 的话 this 将会失效。
React.createClass
注意,我们在 onClick 属性上绑定了 this.handleClick。当点击事件被触发时,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;
除此之外,我们也可以在 constructor 中来改变 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 mixins 的特性将不能被使用了。
React.createClass
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
但在 ES6 中,不支持mixins 。
建议
Facebook 官方的建议是,等到 ES6 中的类对所有特性有完整支持的时候弃用 React.createClass。但现在,凭感觉去使用吧,它们本质上还是殊途同归的两种方式—说到底他们都是类!
原文地址:https://toddmotto.com/react-create-class-versus-component/
参考译文地址:https://www.peachis.me/react-createclass-versus-extends-react-component/
- React.createClass 对决 extends React.Component
- React.createClass versus extends React.Component
- React.createClass和extends Component的区别
- React:createClass 和 extends Component的区别
- React.createClass和extends Component的区别
- react---react组件创建,通过React.createClass方法与class App extends Component方法的区别
- react---react组件创建,通过React.createClass方法与class App extends Component方法的区别
- react知识(一)React.createClass Vs React.Component
- React createClass 和 Component 有什么区别
- React.createClass
- React.createClass( ) 和 React.Component( ) 有什么区别?
- React入门 createClass使用说明
- 在React中使用extends React.Component定义的组件
- 【React】React.Component小结
- React学习笔记(2)-React.createClass、this.props.children
- react js component
- React - Component Compositon (2)
- React Component生命周期
- java面向对象 第一章 抽象和封装
- Qt on Android c++与Java互相交互
- 分库分表
- MYSQL
- NuttX 任务管理
- React.createClass 对决 extends React.Component
- 大话数据结构三:线性表的链式存储结构(静态链表)
- Rviz之tf坐标关系
- 获取列表中重复元素的索引值
- ./ffmpeg: error while loading shared libraries: libavdevice.so.57
- Git。添加。提交代码时报错,
- 开发者开发中遇到的设计模式大全
- 数据库
- 提升幸福感的物件