转载 React.createClass 对决 extends React.Component
先给出结论,这其实是殊途同归的两种方式。过去我们一般都会使用 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
这个函数返回了一个对象,这个对象的所有属性将会作为组件的初始化属性。
import 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 并且更少地驱动了“API”(译注:这里“更少地驱动了 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
时 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> ); }
我们可以像下面这样在行内代码中绑定正确的执行上下文:
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
使用 React.createClass
的话,我们可以在创建组件时添加一个叫做 mixins
的属性,并将可供混合的类的集合以数组的形式赋给 mixins
。
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://www.peachis.me/react-createclass-versus-extends-react-component/
转载于:https://www.cnblogs.com/xiaozhumaopao/p/8311307.html
转载 React.createClass 对决 extends React.Component相关推荐
- React.createClass和extends Component的区别
语法区别 propType 和 getDefaultProps 状态的区别 this区别 Mixins 语法区别 React.createClass import React from 'react' ...
- [react] React.createClass和extends Component的区别有哪些?
[react] React.createClass和extends Component的区别有哪些? 1.语法 React.createClass和extends采用函数构造 extends Comp ...
- 如何在React JS组件和React JS App中添加CSS样式?
In this tutorial, we will only work with CSS styles. Please ensure you have basic knowledge of HTML, ...
- React 全家桶(react脚手架 redux react-redux react-router-dom ui库 reactHook)含 自定义hook的方法及使用
文章目录 React 入门 React 简介 React 为何物 为何学习 React React 初体验 来一发 Hello React 创建虚拟 DOM 的两种方式:JS 和 JSX 虚拟 DOM ...
- React学习笔记一(React入门+JSX+脚手架)
文章目录 1. React介绍和特点 1.1 React是什么 1.2 React的特点 2. React的开发依赖 2.1 React的三个依赖 2.2 Babel和React的关系 2.3 Rea ...
- php继承exten,es6,extends_react中通过extend继承,父组件为什么能访问子组件的属性,es6,extends,react.js - phpStudy...
react中通过extend继承,父组件为什么能访问子组件的属性 代码如下,在父类的componentWillMount方法中输出 this,打印的却是子类 item 通过webpack的编译后文件中 ...
- React router 的 Route 中 component 和 render 属性理解
React router 的 Route 中 component 和 render 属性理解 Route 标签的三个互斥属性 render.component.children Route 就是用来匹 ...
- React.createClass()方法
react组件 -- React.createClass()方法 1.React.createClass()方法用于生成一个组件类 2.所有组件类都必须有自己的render方法,用于输出组件 3.假如 ...
- 04.React事件 方法、 React定义方法的几种方式 获取数据 改变数据 执行方法传值...
2019独角兽企业重金招聘Python工程师标准>>> 一.基本用法 在以类继承的方式定义的组件中,为了能方便地调用当前组件的其他成员方法或属性(如:this.state),通常需要 ...
最新文章
- 每日一皮:据说PM就是这样忍受你的!
- Redis-序列化和存储模式
- Oracle 数据库修改配置文件sga_target参数的值,sga_target值太小导致数据库服务起不来问题解决,调大sga_target参数方法
- ORACLE 动态SQL中的多个单引号
- 在计算机中 鼠标器属于,在计算机中,鼠标器属于()。
- 《科学+ 预见人工智能》——物理学家的管理方式
- python采用面向对象编程模式吗_在python中,面向对象还有用吗?
- iOS 推送通知及推送扩展
- mongo php 自增,PHP7下MongoDB自增或自减一个字段的值
- crossorigin注解添加了解决不了跨域问题_springboot 处理跨域的2种方式
- Spring Boot——2分钟构建spring web mvc REST风格HelloWorld
- 标识符的作用域与可见性
- xpraid安装_XP系统怎么安装raid驱动|XP系统安装raid驱动的方法
- PMP考试知识总结【精华--持续更新】
- 富士通Fujitsu DPK9500GA Pro 打印机驱动
- ArcGIS Pro与ArcGis区别
- win10解除usb禁用_Win10系统禁用usb存储设备的设置方法
- 数学建模与数据分析中的主成分分析
- 服务器系统浏览器打不开,电脑浏览器打不开解决方法
- MVVM和MCV模式
热门文章
- Valve CEO:脑机接口技术可加强游戏体验远超“肉体外设“
- seaborn系列 (17) | 回归模型图lmplot()
- [CES 2018] 联想公布全球首款Daydream一体机,第二季度或将发售
- 一些有意思的VR设备介绍
- java 查找一行_Java培训之工具类通用的查询一行多列,非实体
- 数牍科技完成超3亿元A轮融资,隐私工程守护数据全生命周期流通协作
- 清华硕士在家造了一辆车,从设计到加工一个人完成,轻松穿沙漠爬岩石,还人人可拆装...
- 一块CPU就能运行超逼真水流特效!胡渊鸣的算法被这样实现,本人看了都说好...
- Oracle12c 从入门到精通(第二版) 闫红岩 金松河 编著
- github push时候报错解决方法