React生命周期:
componentWillMount
render
componentDidMount
componentWillUpdate
componentDidUpdate
componentWillUnmount
当出现组件嵌套情况时,先渲染父组件,然后再渲染子组件;只有当子组件componentDidMount后,父组件才会componentDidMount。
组件创建时生命周期例子:
import React, {Component} from 'react';import ReactDOM from 'react-dom';import './index.css';import * as serviceWorker from './serviceWorker';class App extends Component{constructor(props){super(props);this.state = {name: 'React'};}render(){console.log('APP render');return (<div>{this.state.name}{this.state.name && <Son1 name={this.state.name + ' - Son1'}/>}</div>);}componentWillMount(){console.log('APP will Mount');}componentDidMount(){window.app = this;console.log('APP Did Mount');}componentWillUpdate(){console.log('APP will Update');}componentDidUpdate(){console.log('APP Did Update');}componentWillUnmount(){console.log('APP Will Unmount');}}class Son1 extends Component {render() {console.log('Son1 render');return (<div>{this.props.name}<GrandSon1 name={this.props.name + ' - Grand'}/></div>);}componentWillMount(){console.log('Son1 will Mount');}componentDidMount(){console.log('Son1 Did Mount');}componentWillUpdate(){console.log('Son1 will Update');}componentDidUpdate(){console.log('Son1 Did Update');}componentWillUnmount(){console.log('Son1 Will Unmount');}}class GrandSon1 extends Component {render() {console.log('GrandSon1 render');return (<div>{this.props.name}</div>);}componentWillMount(){console.log('GrandSon1 will Mount');}componentDidMount(){console.log('GrandSon1 Did Mount');}componentWillUpdate(){console.log('GrandSon1 will Update');}componentDidUpdate(){console.log('GrandSon1 Did Update');}componentWillUnmount(){console.log('GrandSon1 Will Unmount');}}ReactDOM.render(<App />, document.getElementById('root'));// If you want your app to work offline and load faster, you can change// unregister() to register() below. Note this comes with some pitfalls.// Learn more about service workers: https://bit.ly/CRA-PWAserviceWorker.unregister();
上面代码输出日志为:
App will mount
App render
Son1 will mount
Son1 render
GrandSon1 will mount
GrandSon1 render
GrandSon1 did mount
Son1 did mount
App did mount
组件更新时生命周期例子:
app.setState({name: 'Vue'});
控制台输出日志为:
App will update
App render
Son1 will update
Son1 render
GrandSon1 will update
GrandSon1 render
GrandSon1 Did update
Son1 Did update
App Did update
组件卸载(销毁)时生命周期例子:
APP组件render方法:
render(){console.log('APP render');return (<div>{this.state.name}{this.state.name && <Son1 name={this.state.name + ' - Son1'}/>}</div>);}
设置name为’’,来销毁Son1组件:
app.setState({name: ''});
控制台输出日志如下:
App will update
App render
Son1 will unmount
GrandSon1 will unmount
App Did update
组件上下文例子:
import React, {Component} from 'react';import ReactDOM from 'react-dom';import './index.css';import * as serviceWorker from './serviceWorker';import PropTypes from 'prop-types'class App extends Component{getChildContext(){return {color: 'Red'};}constructor(props){super(props);this.state = {name: 'React'};}render(){console.log('APP render');return (<div>{this.state.name && <Son1 name={this.state.name + ' - Son1'}/>}</div>);}componentWillMount(){console.log('APP will Mount');}componentDidMount(){window.app = this;console.log('APP Did Mount');}componentWillUpdate(){console.log('APP will Update');}componentDidUpdate(){console.log('APP Did Update');}componentWillUnmount(){console.log('APP Will Unmount');}}App.childContextTypes = {color: PropTypes.string};class Son1 extends Component {render() {console.log('Son1 render');return (<div>{this.props.name && <GrandSon1 name={this.props.name + '- Grand'}/>}</div>);}componentWillMount(){console.log('Son1 will Mount');}componentDidMount(){console.log('Son1 Did Mount');}componentWillUpdate(){console.log('Son1 will Update');}componentDidUpdate(){console.log('Son1 Did Update');}componentWillUnmount(){console.log('Son1 Will Unmount');}}class GrandSon1 extends Component {render() {console.log('GrandSon1 render');return (<div>{this.props.name} - {this.context.color}</div>);}componentWillMount(){console.log('GrandSon1 will Mount');}componentDidMount(){console.log('GrandSon1 Did Mount');}componentWillUpdate(){console.log('GrandSon1 will Update');}componentDidUpdate(){console.log('GrandSon1 Did Update');}componentWillUnmount(){console.log('GrandSon1 Will Unmount');}}GrandSon1.contextTypes = {color: PropTypes.string};ReactDOM.render(<App />, document.getElementById('root'));// If you want your app to work offline and load faster, you can change// unregister() to register() below. Note this comes with some pitfalls.// Learn more about service workers: https://bit.ly/CRA-PWAserviceWorker.unregister();
当组件嵌套层次比较深的时候,可以利用这种方式将父组件数据传递到子组件。要定义父组件的childContextTypes,实现父组件的getChildContext方法,然后再定义一下子组件的contextTypes就可以在子组件中使用这个上下文数据了。

Notes:
state和props的相同之处:
1. 改变会触发render函数(UI的改变);
state和props的不同之处:
1. state是可读可写的,props是只读的;
- state是组件内部的数据,props来自父组件(外部);
state变化例子:
在下面的例子中,App的render方法中并没有用到state,但是当state发生变化时候(app.setState({name: ‘Vue’})),App组件会重新render。
日志如下:
APP will Update
APP render
APP Did Update
class App extends Component{constructor(props){super(props);this.state = {name: 'React'};}render(){console.log('APP render');return (<div>APP</div>);}componentWillMount(){console.log('APP will Mount');}componentDidMount(){window.app = this;console.log('APP Did Mount');}componentWillUpdate(){console.log('APP will Update');}componentDidUpdate(){console.log('APP Did Update');}componentWillUnmount(){console.log('APP Will Unmount');}}
