React生命周期:

    componentWillMount
    render
    componentDidMount
    componentWillUpdate
    componentDidUpdate
    componentWillUnmount

    当出现组件嵌套情况时,先渲染父组件,然后再渲染子组件;只有当子组件componentDidMount后,父组件才会componentDidMount。

    组件创建时生命周期例子:

    1. import React, {Component} from 'react';
    2. import ReactDOM from 'react-dom';
    3. import './index.css';
    4. import * as serviceWorker from './serviceWorker';
    5. class App extends Component{
    6. constructor(props){
    7. super(props);
    8. this.state = {
    9. name: 'React'
    10. };
    11. }
    12. render(){
    13. console.log('APP render');
    14. return (<div>
    15. {this.state.name}
    16. {this.state.name && <Son1 name={this.state.name + ' - Son1'}/>}
    17. </div>);
    18. }
    19. componentWillMount(){
    20. console.log('APP will Mount');
    21. }
    22. componentDidMount(){
    23. window.app = this;
    24. console.log('APP Did Mount');
    25. }
    26. componentWillUpdate(){
    27. console.log('APP will Update');
    28. }
    29. componentDidUpdate(){
    30. console.log('APP Did Update');
    31. }
    32. componentWillUnmount(){
    33. console.log('APP Will Unmount');
    34. }
    35. }
    36. class Son1 extends Component {
    37. render() {
    38. console.log('Son1 render');
    39. return (<div>
    40. {this.props.name}
    41. <GrandSon1 name={this.props.name + ' - Grand'}/>
    42. </div>);
    43. }
    44. componentWillMount(){
    45. console.log('Son1 will Mount');
    46. }
    47. componentDidMount(){
    48. console.log('Son1 Did Mount');
    49. }
    50. componentWillUpdate(){
    51. console.log('Son1 will Update');
    52. }
    53. componentDidUpdate(){
    54. console.log('Son1 Did Update');
    55. }
    56. componentWillUnmount(){
    57. console.log('Son1 Will Unmount');
    58. }
    59. }
    60. class GrandSon1 extends Component {
    61. render() {
    62. console.log('GrandSon1 render');
    63. return (<div>
    64. {this.props.name}
    65. </div>);
    66. }
    67. componentWillMount(){
    68. console.log('GrandSon1 will Mount');
    69. }
    70. componentDidMount(){
    71. console.log('GrandSon1 Did Mount');
    72. }
    73. componentWillUpdate(){
    74. console.log('GrandSon1 will Update');
    75. }
    76. componentDidUpdate(){
    77. console.log('GrandSon1 Did Update');
    78. }
    79. componentWillUnmount(){
    80. console.log('GrandSon1 Will Unmount');
    81. }
    82. }
    83. ReactDOM.render(<App />, document.getElementById('root'));
    84. // If you want your app to work offline and load faster, you can change
    85. // unregister() to register() below. Note this comes with some pitfalls.
    86. // Learn more about service workers: https://bit.ly/CRA-PWA
    87. serviceWorker.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

    组件更新时生命周期例子:

    1. 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方法:

    1. render(){
    2. console.log('APP render');
    3. return (<div>
    4. {this.state.name}
    5. {this.state.name && <Son1 name={this.state.name + ' - Son1'}/>}
    6. </div>);
    7. }


    设置name为’’,来销毁Son1组件:

    1. app.setState({name: ''});

    控制台输出日志如下:
    App will update
    App render
    Son1 will unmount
    GrandSon1 will unmount
    App Did update

    组件上下文例子:

    1. import React, {Component} from 'react';
    2. import ReactDOM from 'react-dom';
    3. import './index.css';
    4. import * as serviceWorker from './serviceWorker';
    5. import PropTypes from 'prop-types'
    6. class App extends Component{
    7. getChildContext(){
    8. return {
    9. color: 'Red'
    10. };
    11. }
    12. constructor(props){
    13. super(props);
    14. this.state = {
    15. name: 'React'
    16. };
    17. }
    18. render(){
    19. console.log('APP render');
    20. return (<div>
    21. {this.state.name && <Son1 name={this.state.name + ' - Son1'}/>}
    22. </div>);
    23. }
    24. componentWillMount(){
    25. console.log('APP will Mount');
    26. }
    27. componentDidMount(){
    28. window.app = this;
    29. console.log('APP Did Mount');
    30. }
    31. componentWillUpdate(){
    32. console.log('APP will Update');
    33. }
    34. componentDidUpdate(){
    35. console.log('APP Did Update');
    36. }
    37. componentWillUnmount(){
    38. console.log('APP Will Unmount');
    39. }
    40. }
    41. App.childContextTypes = {
    42. color: PropTypes.string
    43. };
    44. class Son1 extends Component {
    45. render() {
    46. console.log('Son1 render');
    47. return (<div>
    48. {this.props.name && <GrandSon1 name={this.props.name + '- Grand'}/>}
    49. </div>);
    50. }
    51. componentWillMount(){
    52. console.log('Son1 will Mount');
    53. }
    54. componentDidMount(){
    55. console.log('Son1 Did Mount');
    56. }
    57. componentWillUpdate(){
    58. console.log('Son1 will Update');
    59. }
    60. componentDidUpdate(){
    61. console.log('Son1 Did Update');
    62. }
    63. componentWillUnmount(){
    64. console.log('Son1 Will Unmount');
    65. }
    66. }
    67. class GrandSon1 extends Component {
    68. render() {
    69. console.log('GrandSon1 render');
    70. return (<div>
    71. {this.props.name} - {this.context.color}
    72. </div>);
    73. }
    74. componentWillMount(){
    75. console.log('GrandSon1 will Mount');
    76. }
    77. componentDidMount(){
    78. console.log('GrandSon1 Did Mount');
    79. }
    80. componentWillUpdate(){
    81. console.log('GrandSon1 will Update');
    82. }
    83. componentDidUpdate(){
    84. console.log('GrandSon1 Did Update');
    85. }
    86. componentWillUnmount(){
    87. console.log('GrandSon1 Will Unmount');
    88. }
    89. }
    90. GrandSon1.contextTypes = {
    91. color: PropTypes.string
    92. };
    93. ReactDOM.render(<App />, document.getElementById('root'));
    94. // If you want your app to work offline and load faster, you can change
    95. // unregister() to register() below. Note this comes with some pitfalls.
    96. // Learn more about service workers: https://bit.ly/CRA-PWA
    97. serviceWorker.unregister();

    当组件嵌套层次比较深的时候,可以利用这种方式将父组件数据传递到子组件。要定义父组件的childContextTypes,实现父组件的getChildContext方法,然后再定义一下子组件的contextTypes就可以在子组件中使用这个上下文数据了。

    image.png
    Notes:
    state和props的相同之处:
    1. 改变会触发render函数(UI的改变);

    state和props的不同之处:
    1. state是可读可写的,props是只读的;

    1. state是组件内部的数据,props来自父组件(外部);

    state变化例子:

    在下面的例子中,App的render方法中并没有用到state,但是当state发生变化时候(app.setState({name: ‘Vue’})),App组件会重新render。

    日志如下:
    APP will Update
    APP render
    APP Did Update

    1. class App extends Component{
    2. constructor(props){
    3. super(props);
    4. this.state = {
    5. name: 'React'
    6. };
    7. }
    8. render(){
    9. console.log('APP render');
    10. return (<div>
    11. APP
    12. </div>);
    13. }
    14. componentWillMount(){
    15. console.log('APP will Mount');
    16. }
    17. componentDidMount(){
    18. window.app = this;
    19. console.log('APP Did Mount');
    20. }
    21. componentWillUpdate(){
    22. console.log('APP will Update');
    23. }
    24. componentDidUpdate(){
    25. console.log('APP Did Update');
    26. }
    27. componentWillUnmount(){
    28. console.log('APP Will Unmount');
    29. }
    30. }