react component 3种写法
React组件的写法常见有如下3种:
ES5写法React.createClass
ES6写法React.Component
无状态的函数式写法(纯组件-SFC)
下面用实例写一个 SwitchButton 组件的例子
ES5写法React.createClass
React.createClass不用多说,我们最早使用这个方法来构建一个组件“类”,它接受一个对象为参数,对象中必须声明一个render方法,render返回一个组件实例。
import React from 'react';
import ReactDOM from 'react-dom';
var SwitchButton = React.createClass({
getDefaultProp:function() {
return { open: false }
},
getInitialState: function() {
return { open: this.props.open };
},
handleClick: function() {
this.setState({open: !this.state.open})
},
render: function() {
return (
<label onClick={this.handleClick}><input type="checkbox" checked = {this.state.open || false} />{this.state.open ? '开启':'关闭'}</label>
);
}
});
export default SwitchButton;
ES6-写法 React.Component
import React from 'react';
import ReactDOM from 'react-dom';
class SwitchButton extends React.Component {
constructor(props) {
super(props)
this.state = {
open: this.props.open
}
}
handleClick() {
this.setState({open: !this.state.open})
}
render() {
return (
<label onClick={this.handleClick.bind(this)}><input type="checkbox" checked = {this.state.open || false} />{this.state.open ? '开启':'关闭'}</label>
);
}
};
SwitchButton.defaultProps = {
open: false
}
export default SwitchButton;
React.createClass 与 React.Component区别
组件初始状态state的配置不同
React.createClass创建的组件,其状态state是通过getInitialState方法来配置组件相关的状态;
React.Component创建的组件,其状态state是在constructor中像初始化组件属性一样声明的。
函数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不能获取当前组件实例对象。
constContacts extends React.Component { handleClick() { console.log(this); // null }, render() { return ( <div onClick={this.handleClick}></div> ); } };
React.Component 3种手动绑定this的方法:
在构造函数中完成绑定
调用时使用method.bind(this)
使用arrow function来绑定
//在构造函数中完成绑定 constructor(props) { super(props); this.handleClick = this.handleClick.bind(this); //构造函数中绑定 } //调用时使用method.bind(this) <div onClick={this.handleClick.bind(this)}></div> //使用arrow function来绑定 <div onClick={() => this.handleClick()}></div>
无状态的函数式写法(纯组件-SFC)
因为随着应用复杂度不断提升和组件本数量的增加,组件按各自职责被分成不同的类型,于是有一种只负责展示的纯组件出现了,它的特点是不需要管理状态state,数据直接通过props传入,这也符合 React 单向数据流的思想。
无状态组件一般会搭配高阶组件(简称:OHC)一起使用,高阶组件用来托管state,Redux 框架就是通过 store管理数据源和所有状态,其中所有负责展示的组件都使用无状态函数式的写法。
这种模式被鼓励在大型项目中尽可能以简单的写法 来分割原本庞大的组件,而未来 React 也会面向这种无状态的组件进行一些专门的优化,比如避免无意义的检查或内存分配。所以建议大家尽可能在项目中使用无状态组件。
简单的demo
const Todo = (props) => (
return (
<li onClick={props.onClick} style={{textDecoration: props.complete ? "line-through" : "none"}}>
{props.text}
</li>
)
)
无状态组件的特点:
组件不会被实例化,整体渲染性能得到提升
因为组件被精简成一个render方法的函数来实现的,由于是无状态组件,所以无状态组件就不会在有组件实例化的过程,无实例化过程也就不需要分配多余的内存,从而性能得到一定的提升。
组件不能访问this对象
无状态组件由于没有实例化过程,所以无法访问组件this中的对象,例如:this.ref、this.state等均不能访问。若想访问就不能使用这种形式来创建组件
组件无法访问生命周期的方法
因为无状态组件是不需要组件生命周期管理和状态管理,所以底层实现这种形式的组件时是不会实现组件的生命周期方法。所以无状态组件是不能参与组件的各个生命周期管理的。
无状态组件只能访问输入的props,同样的props会得到同样的渲染结果,不会有副作用
如何选择哪种方式创建组件
能用React.Component创建的组件的就尽量不用React.createClass形式创建组件。
除此之外,创建组件的形式选择还应该根据下面来决定:
1、只要有可能,尽量使用无状态组件创建形式。
2、否则(如需要state、生命周期方法等),使用
React.Component
这种es6形式创建组件