react组件的生命周期
写在前面:
阅读了多遍文章之后,自己总结了一个。一遍加强记忆,和日后回顾。
一、实例化(初始化)
var Button = React.createClass({ getInitialState: function() { return { data: 0 }; }, setNewNumber: function() { this.setState({ data: this.state.data + 1 }) }, render: function() { var show = (this.state.data % 2 === 0); return ( <div> <button onClick = {this.setNewNumber}>INCREMENT</button> { show && <Content myNumber = {this.state.data}></Content> } </div> ); } }); var Content = React.createClass({ getDefaultProps: function() { console.log('getDefaultProps'); return { name: 'gdq'}; }, getInitialState: function() { console.log('getInitialState'); return { time: 22 }; }, componentWillMount: function() { console.log('componentWillMount') }, componentDidMount: function() { console.log('componentDidMount') }, render: function() { return ( <div> <h3>{this.props.myNumber}</h3> </div> ); } }); ReactDOM.render( <div> <Button /> </div>, document.getElementById('example2') );
运行结果:
- 创建阶段:getDefaultProps()
该阶段主要发生在定义组件类的时候,即调用React.createClass的时候。这个阶段getDefaultProps() 会被调用一次,并缓存起来——在多个类实例之间共享。在组件的任何实例被创建之前,我们(的代码逻辑)不能依赖这里的this.props
。这个方法只负责返回一个对象,然后与合并父组件的相应属性挂载到this.props中。
2.初始化阶段:(每个组件被使用的时候都会有,包括Unmount后重新Mount的组件, 如上面的<Conent />)
getInitialState() :该方法在组件的一个生命周期中(从初始化挂载到销毁为一个),只会执行一次;负责返回一个对象,成为this.state的初始值
componentWillMount() :在新实例挂载到DOM,我们的业务逻辑可以写在这个阶段,例如修改 this.state,启动个计时器什么的。
render() :返回组件的虚拟DOM,等待reactDOM.render()把该组件渲染都真实的DOM中,
使用规则
a:只能访问this.porps, this.state,而不能修该
b:不能操作DOM
c:只能有一个顶级元素
d:可以返回null, false, 任何组件
componentDidMount() :组件成功渲染到真实DOM后开始执行,在该方法中可通过this.getDOMNode()
访问到真实的DOM元素。此时已可以使用其他类库来操作这个DOM。(在服务端渲染中,该方法不会被调用)。例如:发送ajax请求。
二、存在期(组件已经挂载到真实DOM中,主要就是更新操作)
var Button = React.createClass({ getInitialState: function() { return { data: 0 }; }, setNewNumber: function() { this.setState({ data: this.state.data + 1 }) }, render: function() { return ( <div> <button onClick = {this.setNewNumber}>INCREMENT</button> <Content myNumber = {this.state.data}></Content> </div> ); } }); var Content = React.createClass({ componentWillReceiveProps: function(newProps) { console.log('componentWillReceiveProps') }, shouldComponentUpdate: function(newProps, newState) { console.log('shouldComponentUpdate'); return true; }, componentWillUpdate: function(nextProps, nextState) { console.log('componentWillUpdate'); }, componentDidUpdate: function(prevProps, prevState) { console.log('componentDidUpdate') }, render: function() { return ( <div> <h3>{this.props.myNumber}</h3> </div> ); } }); ReactDOM.render( <div> <Button /> </div>, document.getElementById('example2') );
结果:
1.更新阶段有两种情况触发,其实就是
a: this.props (从父组件接收的props发生改变)
b: this.state (自己的内部状态发生改变。 this.setState({...}),触发)
2.其实就是a情况比b情况多一个componentWillReceiveProps阶段
componentWillReceiveProps(newProps) : 参数为新接收的props对象,在此阶段允许我们配合newProps修改this.state(是更新阶段唯一可以修改 this.state 的地方)
shouldComponentUpdate(nextProps, nextState) : 返回true(默认)/false, 判断是否执行本次更新。若为false,则跳过后面阶段,不执行更新。
a: 不允许修改props,state(this和next都不允许)
b: 一般不需要使用,只在项目进入性能瓶颈时,在这里进行性能优化
componentWillUpdate(nextProps, nextState) :与componentWillMount方法类似,组件上会接收到新的props或者state渲染之前,调用该方法。但是不可以在该方法中更新state和props。
render() : 构建虚拟DOM,并返回
componentDidUpdate() : 组件在真实DOM中渲染后执行
如使用context,参数中将添加context
三、卸载期(组件从真实DOM中卸载的时候执行)
comonentWillUnmount() :组件被移除(从真实DOM中卸载)之前被调用,可以用于做一些清理工作,在componentDidMount
方法中添加的所有任务都需要在该方法中撤销,比如创建的定时器或添加的事件监听器。