关键词:
React创建组件具体的三种方式:
1.函数式定义的无状态组件
2.es5原生方式React.createClass定义的组件
3.es6形式的extends React.Component定义的组件
虽然有三种方式可以定义React组件,但是它们有什么不同呢?什么情况下应该使用哪种定义方式呢?请继续往下看
接下来我们先说一下三种方式有什么区别?
1.无状态函数式组件
它是为了创建纯展示组件,这种组件只负责根据传入的props
来展示,不涉及到要state
状态的操作。
无状态函数式组件形式上表现为一个只带有一个render
方法的组件类,通过函数形式或者ES6 arrow function的形式在创建,并且该组件是无state
状态的。具体的创建形式如下:
function HelloComponent(props, /* context */) return <div>Hello props.name</div> ReactDOM.render(<HelloComponent name="Sebastian" />, mountNode)
无状态组件的创建形式使代码的可读性更好,并且减少了大量冗余的代码,精简至只有一个render方法,大大的增强了编写一个组件的便利,除此之外无状态组件还有以下几个显著的特点:
1. 组件不会被实例化,整体渲染性能得到提升
2.组件不能访问this对象
3.组件无法访问生命周期
4.无状态组件 只能访问输入的props,同样的props会得到同样的渲染结果,不会有副作用
无状态组件被鼓励在大型项目中尽可能以简单的写法来分割原本庞大的组件,未来React也会这种面向无状态组件在譬如无意义的检查和内存分配领域进行一系列优化,所以只要有可能,尽量使用无状态组件。
2.React.createClass
`React.createClass`是react刚开始推荐的创建组件的方式,这是ES5的原生的JavaScript来实现的React组件,其形式如下:
var InputControlES5 = React.createClass( propTypes: //定义传入props中的属性各种类型 initialValue: React.PropTypes.string , defaultProps: //组件默认的props对象 initialValue: ‘‘ , // 设置 initial state getInitialState: function() //组件相关的状态对象 return text: this.props.initialValue || ‘placeholder‘ ; , handleChange: function(event) this.setState( //this represents react component instance text: event.target.value ); , render: function() return ( <div> Type something: <input onChange=this.handleChange value=this.state.text /> </div> ); ); InputControlES6.propTypes = initialValue: React.PropTypes.string ; InputControlES6.defaultProps = initialValue: ‘‘ ;
与无状态组件相比,React.createClass
和后面要描述的React.Component
都是创建有状态的组件,这些组件是要被实例化的,并且可以访问组件的生命周期方法。
但是随着React的发展,React.createClass存在的问题就暴露出来了:
- React.createClass会自绑定函数方法(不像React.Component只绑定需要关心的函数)导致不必要的性能开销,增加代码过时的可能性。
- React.createClass的mixins不够自然、直观;React.Component形式非常适合高阶组件(Higher Order Components--HOC),它以更直观的形式展示了比mixins更强大的功能,并且HOC是纯净的JavaScript,不用担心他们会被废弃。
3.React.Component
React.Component
是以ES6的形式来创建react的组件的,是React目前极为推荐的创建有状态组件的方式,最终会取代React.createClass
形式;相对于 React.createClass
可以更好实现代码复用。将上面React.createClass
的形式改为React.Component
形式如下:
class InputControlES6 extends React.Component constructor(props) super(props); // 设置 initial state this.state = text: props.initialValue || ‘placeholder‘ ; // ES6 类中函数必须手动绑定 this.handleChange = this.handleChange.bind(this); handleChange(event) this.setState( text: event.target.value ); render() return ( <div> Type something: <input onChange=this.handleChange value=this.state.text /> </div> ); InputControlES6.propTypes = initialValue: React.PropTypes.string ; InputControlES6.defaultProps = initialValue: ‘‘ ;
4.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
函数来说,其绑定可以有:
constructor(props) super(props); this.handleClick = this.handleClick.bind(this); //构造函数中绑定
<div onClick=this.handleClick.bind(this)></div> //使用bind来绑定
<div onClick=()=>this.handleClick()></div> //使用arrow function来绑定
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.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>)
参考文献:
- React 组件构造方法: ES5 (createClass) 还是 ES6 (class)?
- React.createClass 对比 extends React.Component
- 应该如何选择:React.createClass, ES6 Classes, 无状态函数式组件
- React中函数式声明组件
- React Mixin 的前世今生
react创建组件的三种方式
react创建组件的三种方式: 1、函数式无状态组件 2、es5方式React.createClass组件 3、es6方式extendsReact.Component 三种创建方式的异同 1、函数式无状态组件 (1)语法1functionmyComponent(props){2return3<div>Hello{pro... 查看详情
react之向路由组件传递参数的三种方式(代码片段)
文章目录向路由组件传递参数的三种方式params参数Home/Message/index.jsx:Home/Message/Detail/index.jsx:search参数Home/Message/index.jsx:Home/Message/Detail/index.jsx:state参数Home/Message/index.jsx:Home/Message/Detail/index.jsx: 查看详情
js中创建函数的三种方式及区别(代码片段)
...执行。自执行函数严格来说也叫函数表达式,它主要用于创建一个新的作用域,在此作用域内 查看详情
检测数据类型的三种方式及区别(代码片段)
vara="iamstring";varb=[1,2,3];varc=newString("abc");//String类实例对象//typeof:null对象数组都是返回Object类型console.log(typeofa);//stringconsole.log(typeofb);//objectconsole.log(typeofc);//object//instanceof无法检测是字符 查看详情
reactnative创建组件的三种方式
创建组件的三种方式1.ES6创建组件的方式exportdefaultclassHelloComponentextendsComponent{render(){return<Textstyle={{color:‘red‘}}>Hello</Text>}}2.ES5创建组件的方式varHelloComponent=React.createClass({render(){retu 查看详情
创建函数的三种方式及区别
1.函数声明function sum1(n1,n2){ return n1+n2; };2.函数表达式,又叫函数字面量var sum2=function(n1,n2){ return n1+n2;};两者的区别:解析器会先读取函数声明,并使其在执 查看详情
react组件通讯的三种方式(代码片段)
父组件传递数据给子组件父组件提供要传递的state数据给子组件标签添加属性,值为state中的数据子组件中通过props接收父组件中传递的数据classParentextendsReact.Componentstate=lastName:'王'render()return(<divstyle=background:'... 查看详情
react创建组件的几种方式及其区别(代码片段)
react创建组件有如下几种方式 ①.函数式定义的无状态组件 ②.es5原生方式React.createClass定义的组件 ③.es6形式的extendsReact.Component定义的组件1、无状态函数式组件创建无状态函数式组件形式是从React0.14版本开始出... 查看详情
react路由传参的三种方式(代码片段)
React路由传参的三种方式方式一:通过params1.路由表中<Routepath=‘/sort/:id‘component=Sort></Route> 2.Link处HTML方式<Linkto=‘/sort/‘+‘2‘activeClassName=‘active‘>XXXX</Link> ... 查看详情
数组的三种方式总结多维数组的遍历及arrays类的常用方法总结(代码片段)
一.数组的三种方式总结 1.创建数组Java语言使用new操作符来创建数组,语法如下:arrayRefVar=newdataType[arraySize];上面的语法语句做了两件事:一、使用dataType[arraySize]创建了一个数组。二、把新创建的数组的引用赋值给变量ar... 查看详情
03react之创建component
...的定义方式呢?下面就简单介绍一下。无状态函数式组件创建无状态 查看详情
vue中实现路由跳转的三种方式详细分解(代码片段)
...数3.添加到Vue.use()身上–注册全局RouterLink和RouterView组件4.创建路由规则数组–路径和组件名对应关系5.用规则生成路由对象6.把路由对象注入到newVue实例中7.用router-view作为挂载点,切换不同的路由页面二、声明式-router-link【实现跳... 查看详情
react全家桶详细讲解-图文并茂(代码片段)
...件传递数据给父组件react-兄弟组件传递五、react-生命周期创建时(挂载阶段)更 查看详情
react全家桶详细讲解-图文并茂(代码片段)
...件传递数据给父组件react-兄弟组件传递五、react-生命周期创建时(挂载阶段)更 查看详情
python创建虚拟环境的三种方式(代码片段)
Python创建虚拟环境的三种方式比较Python创建虚拟环境的三种方式首先:为什么需要虚拟环境?PipenvvsVirtualenvvsConda1.Virtualenv2.Pipenv3.Conda参考资料Python创建虚拟环境的三种方式首先:为什么需要虚拟环境?在使用Python... 查看详情
创建servlet的三种方式(代码片段)
第一种方式,实现Servlet接口1packagecom.example.servlet;23importjava.io.IOException;45importjavax.servlet.Servlet;6importjavax.servlet.ServletConfig;7importjavax.servlet.ServletException;8importjavax.servlet.Ser 查看详情
vue的安装及使用(vue的三种安装使用方式)(代码片段)
...架,是初创项目的首选前端框架。它是以数据驱动和组件化的思想构建的,采用自底向上增量开发的设计。它是轻量级的,它有很多独立的功能或库,我们会根据我们的项目来选用vue的一些功能。它提供了更加简... 查看详情
java数组转list的三种方式及对比(代码片段)
来源| blog.csdn.net/x541211190/article/details/79597236本文介绍Java中数组转为List三种情况的优劣对比,以及应用场景的对比,以及程序员常犯的类型转换错误原因解析。一.最常见方式(未必最佳)通过 Arrays.asList(strArray) ... 查看详情