React.memo

  1. React.memo

React.memo

如果你的组件在相同 props 的情况下渲染相同的结果,那么你可以通过将其包装在 React.memo 中调用,以此通过记忆组件渲染结果的方式来提高组件的性能表现。这意味着在这种情况下,React 将跳过渲染组件的操作并直接复用最近一次渲染的结果。

React.memo 仅检查 props 变更

例如我们渲染一个斐波那契数列的第40位的值,这是一个很耗时的递归操作,在父组件中修改state,我们知道state变了,会导致组件重新渲染,此时Fib组件也会重新渲染,会去重新计算斐波那契数列的值,由于计算非常耗时,此时页面会夯住;

import React from 'react'

class Fib extends React.Component {
    constructor(props){
        super(props)
    }

    fib = (n) => {
        if (n == 1 || n == 2) return 1
        return this.fib(n - 1) + this.fib(n - 2)
    }

    componentDidUpdate() {
        console.log('重新渲染了')
    }

    render() {
        return <div>
            <div>{this.fib(this.props.n)}</div>
        </div>
    }
}

class Comp extends React.Component {
    constructor(props){
        super(props)
        this.state = {
            count: 0
        }
    }

    render(){
        return <div>
            <p>{this.state.count}</p>
            <button onClick={()=>{this.setState({count: this.state.count + 1})}}>+1</button>
            <Fib n={40}></Fib>
        </div>
    }
}

export default Comp

查看结果发现,每当我们点击按钮,Fib组件都会重新渲染并计算值,性能很差;

而如果我们使用React.memo高阶组件包装一下Fib,此时页面检测到实际上Fib组件的props属性n 并没有发生改变,则跳过渲染组件的操作并直接复用最近一次渲染的结果

只需要这么包一下


// ...
const FibMemo = React.memo(Fib)

class Comp extends React.Component {
    constructor(props){
        super(props)
        this.state = {
            count: 0
        }
    }

    render(){
        return <div>
            <p>{this.state.count}</p>
            <button onClick={()=>{this.setState({count: this.state.count + 1})}}>+1</button>
            <FibMemo n={40}></FibMemo>
        </div>
    }
}

通过结果可以看到,使用React.memo包装了之后,组件没有重复渲染,父组件的行为也正常


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 289211569@qq.com