缓存
- memo
- usememo
- useCallback
memo
主要就是应用于 HTML
memo 是一个高阶组件,用于对组件进行包裹,从而对组件进行优化,减少组件的渲染次数
适用场景
当父元素变化 而子元素不需要变化的时候,用它包裹住组件,减少渲染
场景
父元素
js
import { useCallback, useReducer, useState } from "react";
import Son from "./Son";
function App() {
const [count, setCount] = useState(0);
console.log("父元素渲染");
const handleClick = () => {
setCount(count + 1);
};
return (
<div>
<h1 onClick={handleClick}>父元素--{count}</h1>
<Son />
</div>
);
}
export default App;
子元素
js
function Son() {
console.log("子元素渲染");
return (
<div>
<h1> Son</h1>
</div>
);
}
export default Son;
这个时候你会发现只要 count 改变 父子组件一起渲染,浪费性能
改变子元素
- 这样通过包裹层,当父元素改变的时候,子元素不会重新渲染
js
import React, { memo } from "react";
function Son() {
console.log("子元素渲染");
return (
<div>
<h1> Son</h1>
</div>
);
}
export default memo(Son);
useCallback
- 适用于缓存方法
适用场景
memo 有个致命的缺点 就是当父元素给子元素传方法的时候,子元素还是会重新渲染
这个时候就需要 useCallback 来包裹方法,从而减少子元素的渲染,
两个参数 第一个缓存的方法,第二个是依赖项 要是不写则每次都会重新生成一个方法
场景
父元素
js
import { useCallback, useReducer, useState } from "react";
import Son from "./Son";
function App() {
const [count, setCount] = useState(0);
console.log("父元素渲染");
const handleClick = () => {
setCount(count + 1);
};
const fn = () => {};
return (
<div>
<h1 onClick={handleClick}>父元素--{count}</h1>
<Son fn1={fn} />
</div>
);
}
export default App;
子元素
js
import React, { memo } from "react";
function Son() {
console.log("子元素渲染");
return (
<div>
<h1> Son</h1>
</div>
);
}
export default memo(Son);
注意
- 这种情况 缓存失效了,因为每次父元素渲染的时候,都会重新生成一个 fn,所以子元素还是会重新渲染
改变父元素
js
import { useCallback, useReducer, useState } from "react";
import Son from "./Son";
function App() {
const [count, setCount] = useState(0);
console.log("父元素渲染");
const handleClick = () => {
setCount(count + 1);
};
// 缓存,依赖项必须写,不然每次都会重新生成一个方法
const fn = useCallback(() => {}, []);
return (
<div>
<h1 onClick={handleClick}>父元素--{count}</h1>
<Son fn1={fn} />
</div>
);
}
export default App;
usememo
- 适用于属性,也可用于方法
适用场景
memo 有个致命的缺点 就是当父元素给子元素传属性的时候,子元素还是会重新渲染
这个时候就需要 useMemo 来包裹属性,从而减少子元素的渲染,
两个参数 第一个缓存的方法,第二个是依赖项 要是不写则每次都会重新生成一个方法
场景
父元素
js
import { useCallback, useReducer, useState, useMemo } from "react";
import Son from "./Son";
function App() {
const [count, setCount] = useState(0);
console.log("父元素渲染");
const handleClick = () => {
setCount(count + 1);
};
const arr = [1, 2, 3, 4, 5];
return (
<div>
<h1 onClick={handleClick}>父元素--{count}</h1>
<Son arr={arr} />
</div>
);
}
export default App;
子元素
js
import React, { memo } from "react";
function Son() {
console.log("子元素渲染");
return (
<div>
<h1> Son</h1>
</div>
);
}
export default memo(Son);
注意
- 这种情况 缓存失效了,因为每次父元素渲染的时候,都会重新生成一个 arr,所以子元素还是会重新渲染
改变父元素
js
import { useCallback, useReducer, useState, useMemo } from "react";
import Son from "./Son";
function App() {
const [count, setCount] = useState(0);
console.log("父元素渲染");
const handleClick = () => {
setCount(count + 1);
};
const arr = useMemo(() => {
return [1, 2, 3, 4, 5];
}, []);
return (
<div>
<h1 onClick={handleClick}>父元素--{count}</h1>
<Son arr={arr} />
</div>
);
}
export default App;
- 适用于方法
js
import { useCallback, useReducer, useState, useMemo } from "react";
import Son from "./Son";
function App() {
const [count, setCount] = useState(0);
console.log("父元素渲染");
const handleClick = () => {
setCount(count + 1);
};
const arr = useMemo(() => {
return [1, 2, 3, 4, 5];
}, []);
const func1 = useMemo(() => {
return function () {
console.log("func1");
};
}, []);
return (
<div>
<h1 onClick={handleClick}>父元素--{count}</h1>
<Son arr={arr} func1={func1} />
</div>
);
}
export default App;