React.memo了解及使用

781 阅读2分钟

官网

memo 允许你的组件在 props 没有改变的情况下跳过重新渲染。

memo(Component, arePropsEqual?)

使用 memo 将组件包装起来,以获得该组件的一个 记忆化 版本。通常情况下,只要该组件的 props 没有改变,这个记忆化版本就不会在其父组件重新渲染时重新渲染。但 React 仍可能会重新渲染它:记忆化是一种性能优化,而非保证。

用法:

import { memo } from 'react';


const MemoizedComponent = memo(Component, arePropsEqual?)

参数:

  • Component:要进行记忆化的组件。memo 不会修改该组件,而是返回一个新的、记忆化的组件。它接受任何有效的 React 组件,包括函数组件和 forwardRef 组件。
  • 可选参数 arePropsEqual:一个函数,接受两个参数:组件的前一个 props 和新的 props。如果旧的和新的 props 相等,即组件使用新的 props 渲染的输出和表现与旧的 props 完全相同,则它应该返回 true。否则返回 false。通常情况下,你不需要指定此函数。默认情况下,React 将使用 Object.is 比较每个 prop。

返回值:

memo 返回一个新的 React 组件。它的行为与提供给 memo 的组件相同,只是当它的父组件重新渲染时 React 不会总是重新渲染它,除非它的 props 发生了变化。

React.memo等于是对被包装的组件内的props每次进行一个浅比较,如果传递的数据未发生变化,则不进行渲染,从而提升性能。

例子 【props未改变】

Demo.jsx

添加memo之前:

import React, { useState, memo } from 'react'

function Switch({ color }) {
    console.log("子组件 Switch 渲染");
    return (
        <div style={{ width: '100px', height: '100px', backgroundColor: color }}></div>
    )
}

export default function Demo() {
    const [count, setCount] = useState(0)
    console.log("父组件渲染", count);
    return (
        <div>
            <button onClick={() => setCount(count + 1)}>按钮</button>
            <Switch color="red" />
        </div>
    )
}

运行结果:

点击按钮后

图片.png

添加memo

图片.png

运行结果: 点击按钮

图片.png

根据二者对比结果:

使用memo的组件内,当传递过来的props无数据变化时,外部父组件变化,子组件内部无须重新渲染

通过过使用 memo,你告诉 React 你的组件符合此要求,因此只要其 props 没有改变,React 就不需要重新渲染。

React 通常在其父组件重新渲染时重新渲染一个组件。你可以使用 memo 创建一个组件,当它的父组件重新渲染时,只要它的新 props 与旧 props 相同时,React 就不会重新渲染它。这样的组件被称为 记忆化的(memoized)组件。

例子 【props改变】

但是当组件内props变化,即时使用了 memo ,组件也会变化

import React, { useState, memo } from 'react'

function Switch({ color }) {
    console.log("子组件 Switch 渲染");
    return (
        <div style={{ width: '100px', height: '100px', backgroundColor: color }}></div>
    )
}
const MemoSwitch = memo(Switch)

export default function Demo() {
    const [count, setCount] = useState(0)
    const [color, setColor] = useState('red')

    console.log("父组件渲染", count);
    return (
        <div>
            <button onClick={() => setCount(count + 1)}>页面渲染</button>
            <button onClick={() => {
                let colorS = color === 'red' ? 'blue' : 'red';
                setColor(colorS)
            }}>改颜色</button>
            <MemoSwitch color={color} />
        </div>
    )
}

运行结果:

图片.png