ES6组件写法:

    每个组件实例都有自己的声明周期。

    1. class App extends Component{
    2. render(){
    3. return (<div>App1</div>);
    4. }
    5. componentWillMount(){
    6. console.log('app1 WillMount');
    7. }
    8. componentDidMount(){
    9. console.log('app1 DidMount');
    10. }
    11. componentWillUpdate(){
    12. console.log('app1 WillUpdate');
    13. }
    14. componentWillUnmount(){
    15. console.log('app1 WillUnmount');
    16. }
    17. }

    函数式组件写法:
    可以理解这种写法是ES6组件的一种简写。

    1. const App2 = () => {
    2. return (<div>App2</div>);
    3. }

    JS和HTML混写:
    支持字符串,数组等的渲染,不支持对象object的渲染。实例中展示了条件渲染。

    1. import React, {Component} from 'react';
    2. class List extends Component {
    3. render(){
    4. let name = 'David';
    5. let arr1 = ['A', 'B', 'C', 'D'];
    6. let arr2 = [<p>Nice</p>, <p>Boy</p>];
    7. let obj = {a: 1, b: 2};
    8. let showTitle = false;
    9. return (<div>{arr1.map((item, index) => {
    10. if((index+1) % 2 !== 1) {
    11. return item;
    12. }
    13. })}
    14. <h2>title</h2>
    15. <div>{showTitle && <h3>Title</h3>}</div>
    16. <h2>no title</h2>
    17. <div>{showTitle ? <h3>Title</h3> : <h3>No Title</h3>}</div>
    18. </div>
    19. );
    20. }
    21. }
    22. export default List;

    React虚拟DOM原理:
    https://www.cnblogs.com/zhuzhenwei918/p/7271305.html

    虚拟DOM:
    1. 把jsx编译成js;

    1. 把浏览器构建DOM树的工作交给JS,让JS去构建DOM树;
    2. 把结构数据传给React Render方法,将数据渲染出来;

    Tree-Diff算法:
    虚拟DOM树发生改变的3种情况:
    1. DOM标签发生变化:

    变为,把DIV标签删掉,把新标签SPAN添加进去;

    1. 组件发生变化:
      变为组件,把Header组件删掉,然后添加Content组件;
    2. 列表(数组等)渲染:要为组件添加key的属性,而且此属性要唯一,以此优化渲染性能;
    1. import React, {Component} from 'react';
    2. import ReactDOM from 'react-dom';
    3. import './index.css';
    4. import * as serviceWorker from './serviceWorker';
    5. import Filter from './filter/index'
    6. import List from './list/index'
    7. class Header extends Component {
    8. render(){
    9. return (<div>Header</div>);
    10. }
    11. componentDidMount(){
    12. console.log('Header Mount');
    13. }
    14. componentWillUnmount(){
    15. console.log('Header WillUnmount');
    16. }
    17. }
    18. class Content extends Component {
    19. render(){
    20. return (<div>Content</div>);
    21. }
    22. componentDidMount(){
    23. console.log('Content Mount');
    24. }
    25. componentWillUnmount(){
    26. console.log('Content WillUnmount');
    27. }
    28. }
    29. class App extends Component{
    30. constructor(props){
    31. super(props);
    32. this.state = {
    33. bool: true
    34. };
    35. }
    36. // 修改state 的bool的值,然后Header会被卸载,COntent会被挂载;
    37. render(){
    38. return (<div>
    39. { this.state.bool ? <Header/> : <Content/> }
    40. </div>);
    41. }
    42. }
    43. ReactDOM.render(<App />, document.getElementById('root'));
    44. serviceWorker.unregister();

    Notes:
    渲染Item组件时,如果没有给key,当state按示例中变化时,会有如下的日志输出:
    React Will Update
    Vue Will Update
    Angular WillUnmount

    当指定key后,输出日志为:
    Vue Will Update
    Angular Will Update
    React WillUnmount

    1. import React, {Component} from 'react';
    2. import ReactDOM from 'react-dom';
    3. import './index.css';
    4. import * as serviceWorker from './serviceWorker';
    5. class Item extends Component {
    6. render(){
    7. return (<div>{this.props.item}</div>);
    8. }
    9. componentWillMount(){
    10. console.log(this.props.item + ' Will Mount');
    11. }
    12. componentWillUpdate(){
    13. console.log(this.props.item + ' Will Update');
    14. }
    15. componentDidMount(){
    16. console.log(this.props.item + ' Mount');
    17. }
    18. componentWillUnmount(){
    19. console.log(this.props.item + ' WillUnmount');
    20. }
    21. }
    22. class List extends Component {
    23. render(){
    24. return (<div>{this.props.list.map((item) => <Item key={item} item={item}/>)}</div>);
    25. }
    26. componentWillMount(){
    27. console.log('List Will Mount');
    28. }
    29. componentDidMount(){
    30. console.log('List Mount');
    31. }
    32. componentWillUnmount(){
    33. console.log('List WillUnmount');
    34. }
    35. }
    36. class App extends Component{
    37. constructor(props){
    38. super(props);
    39. this.state = {
    40. list: ['Vue', 'Angular', 'React']
    41. };
    42. }
    43. render(){
    44. return (<div>
    45. <List list={this.state.list}/>
    46. <input type='button' onClick={this.change.bind(this)} value='Change'/>
    47. </div>);
    48. }
    49. componentWillMount(){
    50. console.log('App Will Mount');
    51. }
    52. componentDidMount(){
    53. console.log('App Mount');
    54. }
    55. componentWillUnmount(){
    56. console.log('App WillUnmount');
    57. }
    58. change(){
    59. this.setState({list: ['Angular', 'React']});
    60. }
    61. }
    62. ReactDOM.render(<App />, document.getElementById('root'));
    63. // If you want your app to work offline and load faster, you can change
    64. // unregister() to register() below. Note this comes with some pitfalls.
    65. // Learn more about service workers: https://bit.ly/CRA-PWA
    66. serviceWorker.unregister();


    总结:
    1. React通过制定大胆的Diff策略,将O(n3)复杂度的问题转换成O(n)复杂度的问题;

    1. React 通过分层求异的策略,对tree diff进行算法优化;
    2. React 通过相同类生成相似树形结构,不同类生成不同树形结构的策略对component diff进行算法优化;
    3. React 通过设置唯一key的策略,对element diff进行算法优化;