react类组件性能优化-避免不必要的重新渲染

setState() 的两个作用: 1. 修改 state 2. 更新组件(UI)

过程:父组件重新渲染时,也会重新渲染子组件。但只会渲染当前组件子树(当前组件及其所有子组件)

组件性能优化

减少不必要的更新(执行render函数)

减轻state

  • 只存储跟组件渲染相关的数据

  • 不用做渲染的数据不要放在 state 中,比如定时器 id等

  • 对于这种需要在多个方法中用到的数据,应该直接放在 this 中

    • this.xxx = 'bbb'

    • this.xxx

class Hello extends Component {
    state = {
      timerId: null
    }
    componentDidMount() {
        // timerId存储到this中,而不是state中
        this.timerId = setInterval(() => {}, 2000)
    }
    componentWillUnmount() {
        clearInterval(this.timerId)
    }
    render() { … }
}

同理:vue中不要把和渲染无关的数据放到data中

shouldComponentUpdate

父组件的数据变化了,setState()会引起所有后代子组件也被更新,这种思路很清晰,但有缺点:

子组件没有任何变化时也会重新渲染 (接收到的props没有发生任何的改变)。如何避免不必要的重新渲染呢?

此时就需要使用shouldComponentUpdate来进行优化

作用:

通过返回值决定该组件是否重新渲染,返回 true 表示重新渲染,false 表示不重新渲染

触发时机:

render之前

参数:它有两个形参

  • 第一个参数:当前即将要使用的props

  • 第二个参数:当前即将要使用的state

class Hello extends Component {
    shouldComponentUpdate() {
        // 根据条件,决定是否重新渲染组件
        return false
    }
    render() {…}
}

PureComponent

纯组件-浅层对比:

React .PureComponent 与 React .Component 功能相似, 对于引用类型来说:只比较对象的引用(地址)是否相同

例如:

const obj = { number: 0 }
const newObj = obj
newObj.number = 2
console.log(newObj === obj) // tru

所以PureComponent内部比较:

最新的state.obj === 上一次的state.obj ,如果为true,就不重新渲染组件

注意:

不要直接修改源数据,错误做法:

state = { obj: { number: 0 } }
// 错误做法
state.obj.number = 2
setState({ obj: state.obj })

区别:

PureComponent 内部自动实现了 shouldComponentUpdate 钩子,不需要手动比较

原理:

纯组件内部自动通过对比前后两次 props 和 state 的值,来决定是否重新渲染组件

// class Hello extends React.Component { // 普通组件
class Hello extends React.PureComponent { // 纯组件
    render() {
        return (
        	
纯组件
) } }

注意:

只有在性能优化的时候可能会用到纯组件,不要所有的组件都使用纯组件,因为纯组件需要消耗性能进行对比

结论

并不是所有的子组件都一定要随着祖先组件的更新而更新

shouldComponentUpdate用来自定义更新逻辑

你可能感兴趣的:(前端,性能优化,react,javascript)