目前作者所知道的创建react组件的方式有三种:
- 函数式定义(无状态组件)
function MyComponent(props){
return(
<h1>mycomponent</h1>
)
}
- es5原生方式
const MyComponent=React.createClass({
render:function () {
return <h1>mycomponent</h1>
}
})
- es6中class类的方式(有状态组件)
class MyConponent extends React.Component{
constructor(props){
super(props);
}
render() {
return (
<h1>mycomponent</h1>
);
}
}
注意:无论使用哪种方式创建组件,组件名称的首字母都必须大小,因为我们写的是JSX,最后是需要通过babel转义成es5的语法的,而babel在进行转义JSX语法时,是调用了 React.createElement() 这个方法,这个方法需要接收三个参数:type, config, children。第一个参数声明了这个元素的类型,当创建自定义组件时没有首字母小写时, 而 babel 在转义时把它当成了一个字符串 传递进去了;当首字母大写时,babel 在转义时传递了一个变量进去。问题就在这里,如果传递的是一个字符串,那么在创建虚拟DOM对象时,React会认为这是一个原生的HTML标签,但是这显然不是一个原生的HTML标签,因此去创建一个不存在的标签肯定是会报错的。如果首字母大写,那么就会当成一个变量传递进去,这个时候React会知道这是一个自定义组件,因此他就不会报错了。
那么问题来了,这三种方式有啥区别呢?这里说明一个问题,很多时候同一种效果往往有很多种实现方式,所以我们在学习的过程中要避免章节化思维,要对技术进行横向比较,这样能帮你更 加深入的理解各种方式的优缺点。
1.函数式定义和类定义的对比
函数式定义组件没有state和生命周期函数且不能访问this,而类定义中这些都可以有。
2.类定义和React.createClass原生定义的区别
2.1函数this的绑定
React.createClass创造的组件,其每一个成员函数的this都会自动由React绑定,所以使用时可以直接this.method,而通过class创建组件的成员函数则需要手动绑定,如this.method=this.method.bind(this).
2.2Mixins特性
使用 React.createClass
的话,我们可以在创建组件时添加一个叫做 mixins
的属性,并将可供混合的类的集合以数组的形式赋给 mixins,关于mixins不了解的同学可以参考mixins的前世今生
3.如何选择哪种方式创建组件
由于React团队已经声明React.createClass最终会被React.Component的类形式所取代。但是在找到Mixins
替代方案之前是不会废弃掉React.createClass
形式。所以:
能用React.Component创建的组件的就尽量不用React.createClass形式创建组件。
除此之外,创建组件的形式选择还应该根据下面来决定:
1、只要有可能,尽量使用无状态组件创建形式。
2、否则(如需要state、生命周期方法等),使用`React.Component`这种es6形式创建组件