9、使用递归来实现树形组件,及简单性能优化

父组件:

1
import React, { 2 Component 3 } from "react"; 4 import TreeNode from "../components/TreeNode"; 5 //数据源 6 const treeData = { 7 key: 0, //标识唯⼀性 8 title: "全国", //节点名称显示 9 children: [ 10 //⼦节点数组 11 { 12 key: 6, 13 title: "北⽅区域", 14 children: [{ 15 key: 1, 16 title: "⿊⻰江省", 17 children: [{ 18 key: 6, 19 title: "哈尔滨", 20 },], 21 }, 22 { 23 key: 2, 24 title: "北京", 25 }, 26 ], 27 }, 28 { 29 key: 3, 30 title: "南⽅区域", 31 children: [{ 32 key: 4, 33 title: "上海", 34 }, 35 { 36 key: 5, 37 title: "深圳", 38 }, 39 ], 40 }, 41 ], 42 }; 43 export default class TreePage extends Component { 44 render() { 45 return (<div> 46 <h1 > TreePage </h1> 47 <TreeNode data={treeData}/> </div> 48 ); 49 } 50 }

子组件

import React,{Component} from 'react';
import classnames from "classnames"; //安装

export default class TreeNode extends Component{
    constructor(props) {
        super(props);
        this.state = {
          expanded: false,
        };
      }
      handleExpanded = () => {
        this.setState({
          expanded: !this.state.expanded,
        });
      };//控制三角形图标

      render(){
          const {title, children } = this.props.data;
          const hasChildren = children && children.length>0;
          const {expanded} = this.state;

          return(
              <div>
                  <div className="nodesInner" onClick={this.handleExpanded}>
                  {
                        hasChildren && (
                            <i className={classnames("tri",expanded ? "tri-open":"tri-close" )}></i>
                        )}
                        <span>{title}</span>
                  </div>
                  {
                      hasChildren && expanded && (
                          <div className="children">
                              {
                                  children.map(item=>{
                                      return <TreeNode key={`children${item.key}`} data={item} />
                                  })
                              }
                          </div>
                      )
                  }
              </div>
          )
      }
}

使用shouldComponentUpdate实现简单性能优化

import React,{Component} from 'react'

export default class CommentList extends Component{
    constructor(props) {
        super(props);
        this.state = { comments: [] };
        };
        componentWillMount(){
            setInterval(()=>{
                this.setState({
                    comments:[
                        {
                            author: "⼩明",
                            body: "这是⼩明写的⽂章",
                            },
                            {
                            author: "⼩红",
                            body: "这是⼩红写的⽂章",
                            },
                    ]
                })
            },1000)
        }
    render(){
        const {comments} = this.state;
        return(
            <div>
                <h1>(CommentList)</h1>
                {
                    comments.map((c, i)=>{
                        return <Comment key={i} data={c} />;
                    })
                }
            </div>

        )
    }
}


class Comment extends Component {
    shouldComponentUpdate(nextProps,nextState){
        const { author, body } =nextProps.data;
        const { author: nowAuthor, body: nowBody } = this.props.data;
        if(author === nowAuthor && body === nowBody){
            return false
        }
        return true
    }
    render() {
        console.log("hah");
        const { body, author } = this.props.data;
        return (
        <div>
        <p>作者: {author}</p>
        <p>正⽂:{body}</p>
        <p>---------------------------------</p>
        </div>
 );
}
}

 

函数组件使用React.memo,React.memo(...) 是React v16.6引进来的新属性。它的作⽤和 React.PureComponent 类似,是⽤来控制函数 组件的重新渲染的。

React.memo(...) 其实就是函数组件的 React.PureComponent 。memo和PureComponent 都有一个通病,不能进行嵌套多层数据的判断,所以还是推荐class组件

中的shouldComponentUpdate

import React, { Component,memo } from 'react';

class MemoPage extends Component {
    constructor(props) {
        super(props);
        this.state = {
        counter: 0,
        obj: { num: -1 },
        };
        };
        setCounter = () => {
            this.setState({
            counter: 1 /* ,
            obj: {
            num: 100,
            }, */,
            });
            };
    render() {
        const { counter } = this.state;
        return (
            <div>
                <h1>MemoPage</h1>
                <button onClick={this.setCounter}>按钮</button>
                {/* <PuerCounter counter={counter} obj={obj} /> */}
                <PuerCounter counter={counter} />
            </div>
        );
    }
}


const PuerCounter = memo(props=>{
    console.log("render")
    return <div>{props.counter}</div>
})

export default MemoPage;

 

posted @ 2020-09-13 14:31  雪糕战士  阅读(618)  评论(0编辑  收藏  举报