/**
* React.memo可以对组件进行缓存(浅比较),减少不必要的渲染
* 1.渲染规律
* 父组件渲染会引起子组件渲染
* 子组件渲染不会引起父组件渲染
* 2.性能损耗
* 父组件数据改变,重新渲染,子组件数据未改变,也会渲染(子组件越复杂,无意义的损耗越大).
* 3.性能损耗解决办法:
* 所以需要使用React.memo对子组件进行缓存,只有当子组件真正变化时,子组件才会重新渲染。
* 那子组件什么情况下发发生变化呢?
* ①子组件依赖的props属性改变
* ②子组件中state的状态改变
* ③子组件中使用了useContext的值改变
*
*/
import React, { useState, useMemo } from 'react';
// 子组件:用 React.memo 包裹,默认使用浅比较
const Child = React.memo(function Child({ title, data }) {
console.log('[Child] render', { title, data });
return (
<div>
<h3>{title}</h3>
<div>data.value: {data.value}</div>
</div>
);
});
export default function MemoDemo() {
const [countA, setCountA] = useState(0);
const [countB, setCountB] = useState(0);
// 如果直接写成 const data = { value: countA };
// 每次父组件渲染都会生成新对象,导致 Child 总是重渲染。
// 用 useMemo 稳定对象引用,仅当 countA 变化时才生成新对象。
const data = useMemo(() => ({ value: countA }), [countA]);
return (
<div>
<h2>React.memo 示例</h2>
<div>
<button onClick={() => setCountA(v => v + 1)}>countA +1</button>
<button onClick={() => setCountB(v => v + 1)}>countB +1</button>
</div>
<p>countA: {countA}</p>
<p>countB: {countB}</p>
{/* 只有 title 或 data 引用/内容变化时,Child 才会重新渲染 */}
<Child title="我是子组件" data={data} />
</div>
);
}
console