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;