优化无用渲染

发布于 2024-11-07 07:46:44 字数 4296 浏览 0 评论 0

前述

  • shouldComponentUpdate
  • Pure Component
  • React.memo

描述

每当我们设置 React 中某个 state 时,页面都会重新渲染。即使这个 state 的值没有发生改变,也会触发重新渲染,导致页面性能被占用。

实践

类 - shouldComponentUpdate && PureComponent

普通例子 TestC

import React from 'react';

class TestC extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            count: 0
        }
    }
    
    componentWillUpdate(nextProps, nextState) {
        console.log('componentWillUpdate')
    }
    
    componentDidUpdate(prevProps, prevState) {
        console.log('componentDidUpdate')
        
    }
    
    render() {
        return (
            <div >
            {this.state.count}
            <button onClick={()=>this.setState({count: 1})}>Click Me</button>
            </div>
        );
    }
}
export default TestC;

执行这个页面可以发现,每次点击按钮,页面都会重绘

shouldComponentUpdate

shouldComponentUpdate 重写之前的 TestC 组件:

import React from 'react';

class TestC extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            count: 0
        }
    }
    
    componentWillUpdate(nextProps, nextState) {
        console.log('componentWillUpdate')
    }
    
    componentDidUpdate(prevProps, prevState) {
        console.log('componentDidUpdate')
    }
    
    // 在 compoenentDidUpdate 中拦截重绘
    shouldComponentUpdate(nextProps, nextState) {
        if (this.state.count === nextState.count) {
            return false
        }
        return true
    }
    
    render() {
        return ( 
            <div> 
            { this.state.count } 
            <button onClick = {
                () => this.setState({ count: 1 }) }> Click Me </button> 
            </div>
        );
    }
}

export default TestC

由于在 shouldComponentUpdate 中进行了拦截,所以当 state 没有发生改变的时候,不会触发组件的重绘

PureComponent

Reactv15.5 引入了 PureComponentReact 在进行组件更新时,如果发现这个 Component 是一个 PureComponent ,会将组件现在的 stateprops 和其下一个 stateprops 进行浅比较,如果它们的值没有变化,就不会进行更新。

import React from 'react'

class TestC extends React.PureComponent {
  constructor(props) {
    super(props)
    this.state = {
      count: 0
    }
  }
  
  componentWillUpdate(nextProps, nextState) {
   console.log('componentWillUpdate')
  }
  
  render() {
    return (
      <div>
        { this.state.count }
        <button onClick = {
            () => this.setState({ count: 1 })
        }> Click Me </button>
      </div>
    )
  }
}

export default TestC

可以看到上面 PureComponent 实现了和我们在 shouldComponentUpdate 中实现的功能一样。

但是,我曾遇到一个坑,如果 state 树深度超过 2 可能会出现无论如何改变 state 都无法触发重绘函数

函数组件 - React.memo

函数组件和类不同,没有 shouldComponentUpdate 这些属性

普通例子 TestC

import React from 'react';

const TestC = (props) => {
    console.log(`Rendering TestC :` props)
    return ( 
        <div>
            {props.count}
        </div>
    )
}
export default TestC;
// App.js
<TestC count={5} />

React.memo

React.memoReact v16.6 引入的新特性,它的作用和 React.PureComponent 类似,是用来控制函数组件的重新渲染的。 React.memo(...) 其实就是函数组件的 React.PureComponent

import React from 'react';

let TestC = (props) => {
    console.log('Rendering TestC :', props)
    return ( 
        <div>
        { props.count }
        </>
    )
}
TestC = React.memo(TestC);

export default TestC;

此时,当我们传入 props.count 没有发生改变时,便不会再重绘

结论

  • React.PureComponent 是给 ES6 的类组件使用的
  • React.memo(...) 是给函数组件使用的
  • React.PureComponent 减少 ES6 的类组件的无用渲染
  • React.memo(...) 减少函数组件的无用渲染

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

还如梦归

暂无简介

0 文章
0 评论
22 人气
更多

推荐作者

月光色

文章 0 评论 0

咆哮

文章 0 评论 0

痞味浪人

文章 0 评论 0

宁涵

文章 0 评论 0

军弟

文章 0 评论 0

临走之时

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文