-
调用super的原因:在ES6中,在子类的
constructor
中必须先调用super
才能引用this
-
super(props)
的目的:在constructor
中可以使用this.props
对于一个包含着生命周期的组件,有以下可选的生命周期方法:
-
componentWillMount()
仅在render()
方法前被调用一次,如果在该方法中调用了setState
方法去改变组件的状态值,那么调用render()
后,将会直接看到改变过了的状态值,并且不论状态值怎么改变,componentWillMount()
都不会再被调用 -
componentDidMount()
仅在render()
方法后被立即调用一次(客户端),相对于父组件而言,该方法在子组件中会先被调用。如果需要使用一些JaveScript框架或者类似于setInterval()
这样的方法,建议在该方法内使用。 -
ShouldComponentUpdate(object nextProps, object nextState)
在初始渲染调用render()方法时不会被调用,后面在接受到新的state或者props时,在render()方法前被调用。为防止一些潜在的bug,该方法默认总是返回true。如果你确定state及props改变后不需要渲染组件,那么也可以指定返回false,需要注意的是,这样的结果会导致后面的render()、componentWillUpdate()、componentDidUpdate()都不会被调用。 -
componentWillReceiveProps(object nextProps)
在初始渲染调用render()
方法时不会被调用,当接收到一个新的props时,该方法被调用。我们都知道,如果改变一个状态的值,则会触发render()
方法,所以可以在这个方法里调用setState()
方法去改变一个状态的值,当该方法接收到新的props
时,setState()
就可以避免一次额外的render()
了。
在这个方法里,尤其需要注意一点,就是接收到新的props
一定会触发render()
方法,但是render()
方法被触发不一定是因为接收到了新的props
(具体请戳这里)。如下:class Demo extends React.Component { componentWillReceiveProps(nextProps) { console.log('componentWillReceiveProps is invoked', nextProps.val.name) } render() { return ( <div>{this.state.value}</div> ) } } var data = { name: 'zhou xiao cheng' } ReactDOM.render(<Demo val={data} />, document.getElementById('app')) ReactDOM.render(<Demo val={data} />, document.getElementById('app')) ReactDOM.render(<Demo val={data} />, document.getElementById('app'))
在上面的代码中,
props
没有发生改变,但render()
方法却被调用了两次。 -
componentWillUpdate(object nextProps, object nextState)
在初始渲染调用render()
方法时不会被调用,当接收到新的props及state时,在render()
方法之前被调用。 -
componentDidUpdate(object prevProps, object prevState)
在初始渲染调用render()
方法时不会被调用,当组件更新被刷新到DOM之后被立即调用。 -
componentWillUnmount()
在组件从DOM上卸载前被调用,在这个方法里面,我们主要是完成一些清除操作,比如说清除掉一些过时了的定时器等。
组件规范介绍
除了上面的7个可选的生命周期方法,我们可以将剩下的一些方法称之为组件规范。接下来,我们将会对一些较为常用的组件规范进行介绍。
-
render()
对于一个组件而言,render()
方法是必须的,通常,在这个方法里面,我们都会返回一个元素(如:<div></div>
),但同样也可以返回false
或null
,这意味着我们没有任何东西需要渲染。 -
getInitialState()
在ES6的语法中,这个方法可以写成下面这样(将其写在构造函数中,this.state
的值就是状态初始值),其效果是一样的:class Demo extends React.Component { constructor() { super() this.state = { key: value } }
-
getDefaultProps()
ES6的语法中,写法如下:Demo.defaultProps = {key: value}
ES7中,还可以写成这样(但需要配合Babel转换器进行使用):
class Demo extends React.Component { static defaultProps = { key: value } }
-
propTypes
ES6的语法中,写法如下(想了解更多propTypes请戳官方propTypes介绍):Demo.propTypes = { requiredFunc: React.PropTypes.func.isRequired }
同样,在ES7中,可以写成下面这样:
class Demo extends React.Component { static propTypes = { requiredFunc: React.PropTypes.func.isRequired } }
-
static
ES6语法中,static关键字则允许我们定义一个在组件类上能够调用的静态方法和属性:class Demo extends React.Component { static method = function(){ //doSomething } static propTypes = { requiredFunc: React.PropTypes.func.isRequired } }
//调用静态方法 Demo.method() //调用属性 Demo.propTypes
调用顺序及次数
如果你能理解上面所叙述的,那么,就不难得出下面的结论啦~~~
getDefaultProps()
,调用1次getInitialState()
,调用1次componentWillMount()
,调用1次render()
,调用>=1次componentDidMount()
:仅客户端,调用1次componentWillReceiveProps(object nextProps)
,调用>=0次ShouldComponentUpdate(object nextProps, object nextState)
,调用>=0次componentWillUpdate(object nextProps, object nextState)
,调用>=0次render()
,调用>=1次componentDidUpdate(object prevProps, object prevState)
,调用>=0次componentWillUnmount()
,调用1次
好了,这次就写到这了,望与各君共勉。
参考资料:
https://facebook.github.io/react/docs/reusable-components.html#es6-classes
https://facebook.github.io/react/docs/component-specs.html