这些并不是必要的hook/组件,但有性能问题可以尝试使用
举个例子:
有两个组件,App是父组件,A是子组件。App里有一个按钮点击它会进行setState,所以App会被重新渲染,如果父组件重新渲染,子组件会不会也重新渲染
js
//App.jsx
import { useState, useEffect } from "react";
import A from "./A.jsx";
export default function App() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log("父组件渲染");
});
function click() {
setCount(count + 1);
}
return (
<div className="App">
<button onClick={click}>按钮</button>
<A></A>
</div>
);
}
js
//A.js
import React from "react";
import { useState, useEffect, useMemo, memo } from "react";
const A = () => {
useEffect(() => {
console.log("子组件渲染");
});
return <>123</>;
};
export default A;
点击按钮,可以看到父组件重新渲染,子组件也会重新渲染
但是如果子组件不需要重新渲染,这样就会影响性能了
memo
它是一个高阶组件,只需要用它包裹上面的子组件,就不会重新渲染了
js
const A = memo(() => {
useEffect(() => {
console.log("子组件渲染");
});
return <>123</>;
});
memo 的作用就是只有 props 变的时候,才会重新渲染被包裹的组件
usecallback
然而如果给子组件传入一个函数
js
<A fn={fn}></A>
memo高阶组件失效了,因为每次 function 都是新创建的,也就是每次 props 都会变,这样 memo 就没用了。
这个时候就需要useCallback,它的第二个参数就是依赖项,不改变就不会创建新的函数
js
const fn = useCallback(() => {}, []);
现在memo就有作用了
useMemo
与vue的计算属性类似,使用方法类似于useCallback
当然也可以缓存组件,类似于memo高阶组件,甚至也可以缓存函数,但缓存函数一般用useCallback
js
// useMemo 第一个参数是一个函数,第二个参数是依赖数组
const sum = useMemo(() => {
console.log('Calculating sum...');
return a + b; }, [a, b]); // a 和 b 是依赖项,只有它们发生变化时,才会重新计算 sum
但是如果没有明显性能问题,不需要使用它们,因为缓存本身就需要消耗性能,可读性也会变差,可能会得不偿失。