react组件通信,引出性能优化问题

1.react父子组件之间通过props传递数据,通过callback回调子组件向父组件通信,

我们看下面的伪代码:

class TodoListDemo extends React.Component {
    constructor(props) {
        super(props)
        // 状态(数据)提升
        this.state = {
            list: [
                {
                    id: ‘id-1‘,
                    title: ‘标题1‘
                },
                {
                    id: ‘id-2‘,
                    title: ‘标题2‘
                },
                {
                    id: ‘id-3‘,
                    title: ‘标题3‘
                }
            ],
            footerInfo: ‘底部文字‘
        }
    }
    render() {
        return <div>
            <Input submitTitle={this.onSubmitTitle}/>
            <List list={this.state.list}/>
            {/* 我们发现list数据的渲染,会引起Footer组件的渲染,其实Footer组件的并没有必要渲染 */}
            {/*  React 默认:父组件有更新,子组件则无条件也更新!!!
                            性能优化对于 React 更加重要!
                            SCU 一定要每次都用吗?—— 需要的时候才优化 */}
            <Footer text={this.state.footerInfo} length={this.state.list.length} />
        </div>
    }
    onSubmitTitle = (title) => {
        this.setState({
            list: this.state.list.concat({
                id: `id-${Date.now()}`,
                title
            })
        })
    }
}

export default TodoListDemo

2.解决方案:

(1)可以使用 shouldComponentUpdate  阻止子组件渲染

数据结构简单的时候直接对比可以,但是如果数据结构复杂的时候,不适合深度比较,所以SCU一定是需要的时候再优化

shouldComponentUpdate(nextProps, nextState) {
        if (nextProps.text !== this.props.text
            || nextProps.length !== this.props.length) {
            return true // 可以渲染
        }
        return false // 不重复渲染
    }
  
  为什么要shouldComponentUpdate默认true,而且给你权力来返回false?为什么react不自己去对比 ?
  
  因为一旦code的人写法不规范,会导致页面不刷新的问题,shouldComponentUpdate对比要配合state的不可变值
 
  (2)pureComponent和React.memo
  浅比较已经适用大部分情况(尽量不要做深度比较)
  class写法可以用pureComponent,无状态组件使用React.memo
  pureComponent也有局限性
  pureComponent是传入属性的第一层对比,如果属性内部有变化,会使视图不更新的bug
  如果传入内联函数,每次创建一个新的函数,子组件也会一直渲染更新。
  (3)不可变值immutable.js

相关推荐