Skip to content

memo

约 425 字大约 1 分钟

react性能优化memo

2025-05-23

React.memo作用

组件默认的渲染机制

默认机制:顶层组件发生重新渲染,这个组件树的子级组件都会被重新渲染

在react子传父是 当props 无论发没发声改变 子组件都会渲染

利用React.memo之后就会判断props 是否改变,没改变 子组件不会渲染

import React, { useState } from 'react'

const MemoSon = React.memo(function Son() {
  console.log('子组件被重新渲染了')
  return <div>this is span</div>
})

function App() {
  const [, forceUpdate] = useState()
  console.log('父组件重新渲染了')
  return (
    <>
      <MemoSon />
      <button onClick={() => forceUpdate(Math.random())}>update</button>
    </>
  )
}

export default App

**当引用数据类型是会出现问题 prop没发生改变 也会渲染 **这就要说到他的 props的比对机制

props的比对机制

父组件每次渲染时,直接声明的对象/数组会生成新的引用地址(即使内容相同)

对于props的比较,进行的是‘浅比较’,底层使用 Object.is 进行比较,针对于对象数据类型,只会对比俩次的引用是否相等,如果不相等就会重新渲染,React并不关心对象中的具体属性

// 父组件
function Parent() {
  const [count, setCount] = useState(0);
  
  // ❌ 每次渲染生成新数组
  const list = [1, 2, 3];  

  return (
    <>
      <button onClick={() => setCount(c => c+1)}>渲染 {count}</button>
      <Child list={list} />
    </>
  );
}

// 子组件(使用 React.memo 无效)
const Child = React.memo(({ list }) => <div>{list}</div>);

解决办法

结合useMemo 进行数据缓存

function Parent() {
  const [count, setCount] = useState(0);
  
  // ✅ 使用 useMemo 缓存数组
  const list = useMemo(() => [1, 2, 3], []); // 空依赖数组表示永久缓存

  return (
    <>
      <button onClick={() => setCount(c => c+1)}>渲染 {count}</button>
      <Child list={list} />
    </>
  );
}