React中的组件主要分为无状态组件和有状态组件两类。函数
1,无状态组件主要用来定义模板,接收来自父组件props传递过来的数据,使用{props.xxx}的表达式把props塞到模板里面。无状态组件应该保持模板的纯粹性,以便于组件复用。建立无状态组件以下:this
var Header = (props) = ( <div>{props.xxx}</div> );
2,有状态组件主要用来定义交互逻辑和业务数据(若是用了Redux,能够把业务数据抽离出去统一管理),使用{this.state.xxx}的表达式把业务数据挂载到容器组件的实例上(有状态组件也能够叫作容器组件,无状态组件也能够叫作展现组件),而后传递props到展现组件,展现组件接收到props,把props塞到模板里面。建立有状态组件以下:spa
class Home extends React.Component { constructor(props) { super(props); }; render() { return ( <Header/> //也能够写成<Header></Header> ) } }
这个是官方默认的写法,在构造函数里面默认要传递一个参数进去,而且要调用super()方法,来获取子类的实例。可是比较疑惑的地方是为何要传递这些参数,传递这些参数有什么用?code
由于从render()里面的组件来看,构造函数不传递参数也能够获取到组件实例上的props属性。以下:blog
class Home extends React.Component { constructor() { super(); }; render (){ return( <div> <Header name="俺是子组件实例上props属性"/> </div> ); }; }; class Header extends React.Component { constructor() { super(); }; render() { return ( <div>{this.props.name}</div> //构造函数中并无传递props属性,这里经过{this.props.name}依然获取到了值 ); }; };
这个比较好理解,由于render()方法是子组件原型上的方法,获取实例属性的时候要经过this来访问,若是去掉this就获取不到了。图片
那问题来了,若是咱们要在构造函数中访问props改怎么办呢?此时,咱们就要在constructor构造函数中传递一个props参数,这样就能够访问到子组件实例上的props属性了。以下:文档
class Header extends React.Component { constructor(props) { super(); this.name = props.name; //获取到子组件实例上的props.name属性,赋值给实例属性name }; render() { return ( <div>{this.name}</div> ); }; };
还有一个问题,super(props)方法中为何也要传递一个props属性呢?看下面的例子:原型
class Header extends React.Component { constructor(props) { super(props); this.state = { nameOne: props.name, nameTwo: this.props.name //super()方法中传递了props属性,this.props才能够获取到name属性 } }; render() { return ( <div>{this.state.nameOne}{this.state.nameTwo}</div> ); }; };
其实,props.name和this.props.name的值都是同样的,可是它俩仍是有区别的,props.name中这个props就是子组件的属性props,可是this.props.name中的这个props却不是子组件的属性props,虽然值都是同样的,这个props其实在调用super方法的时候被传递到了Component这个父类中去了,因此this.props.name获取到的是Component父类中的props属性。看下React的源码:源码
发现没,子类super方法把props参数传递给了父类Component,Component把props参数挂载到它的实例属性props上了。因此,你只有给super方法中传递props参数,在构造函数里才能用this,props.xxxit
若是super方法中不传递props参数,获取this.props.name的值就会报错。获取this.props显示为undifined:以下:
class Header extends React.Component { constructor(props) { super(); this.state = { nameOne: this.props.name, nameTwo: this.props }; console.log(this.props.name); //报错 console.log(this.props); //undifined }; render() { return ( <div>{this.state.nameOne}{this.state.nameTwo}</div> ); }; };
这种写法本质是给子组件Header的实例属性state.nameOne和state.nameTwo赋值了一个子组件Header的实例属性props,简单来讲,就是Header子组件建立了一个state属性,而后又把本身的props属性赋值给了本身的state属性。
为何this.props打印出undefined?由于props是调用子组件的时候传入的参数,因此在构造函数内部是访问不到props的,那么对于this.props.name来讲,毫无疑问确定报错。
因此,对与构造函数中的props参数和super中的props参数来讲,若是你不在构造函数中用this.props和props,彻底能够不用传参。反之就要传参。可是对于this.props和props来讲获取到的值都是同样的,因此写哪一个均可以。可是官方文档上是两个参数都有写。因此为了严谨,仍是都写上吧。
可是,我我的仍是喜欢这样的写法。
constructor(props) { super(props); this.state = { name: props.name } };
不加this的是value,加了this的是key。