React有三种创建组件的方式:
一、无状态函数式组件:无状态函数式组件表现为只带一个render方法的组件。
特点:
1、组件不会被实例化,对整体渲染性能有所提升;
2、组件不能访问this对象;
3、组件无法访问生命周期的方法;
4、无状态组件只能访问输入的props。
function HelloWorld (props) {
return <div>Hello {props.name}</div>
}
ReactDOM.render(<HelloWorld name="world" />, example)
二、React.createClass:是ES5原生JS实现的组件,有状态组件
特点:
1、可以实例化,能访问组件的生命周期;
2、会自动绑定函数方法,从而导致不必要的性能开销;
3、React.createClass创建的组件,其每一个成员函数的this都有React自动绑定,任何时候使用,直接使用this.method即可;
4、React.createClass的mixins不够自然,直观。适合高阶组件(还不是很理解)。
如:
const Component = React.createClass({
render: function () {
return <h1>component</h1>
}
})
三、React.component:是以ES6形式创建的组件,也是目前推荐的创建组件的方式,如:
class Component extends React.Component{
constructor(props){
super(props);
}
render() {
return (
<h1>component</h1>
);
}
}
特点:
1、React.Component创建的组件,其成员函数不会自动绑定this,需要手动绑定,否则this不能获取当前组件实例对象
2、3种绑定this的方法:
(1)在构造函数中绑定,如:
constructor(props) {
super(props);
this.myFun= this.myFun.bind(this);
}
(2)在调用时绑定,如:
<div onClick={this.handleClick.bind(this)}></div>
(3)使用箭头函数绑定,如:
<div onClick={(param)=>this.handleClick(param)}></div>
注:
(1)如果有可能,尽量使用无状态组件
(2)如果需要使用state、生命周期等,则使用React.Component这种ES6形式创建组件
(3)无论使用哪种方式创建组件,组件名称的首字母都必须大小,因为我们使用的是JSX语法,最后需要通过babel转义成ES5语法,而babel在进行转义JSX语法时,是调用了 React.createElement() 这个方法,这个方法需要接收三个参数:type, config, children。第一个参数声明了这个元素的类型,当创建自定义组件时如果首字母小写, babel会在转义时按照一个字符串进行传递;当首字母大写时,babel在转义时按照一个变量进行传递。问题就在这里,如果传递的是一个字符串,那么在创建虚拟DOM对象时,React会认为这是一个原生的HTML标签,但是这显然不是一个原生的HTML标签,因此去创建一个不存在的标签肯定是会报错的。如果首字母大写,那么就会当成一个变量传递进去,这个时候React会知道这是一个自定义组件,因此他就不会报错了。