useCallback(fn, dependencies)
useCallback 在多次渲染中缓存一个函数,直至这个函数的依赖发生改变。
import { useCallback } from 'react';
function ProductPage({ productId, referrer, theme }) {
const handleSubmit = useCallback((orderDetails) => {
post('/product/' + productId + '/buy', {
referrer,
orderDetails,
});
}, [productId, referrer]);
// usecallback返回的是一个函数,以来不变,则返回的函数不变
应用一:useCallback和memo配合使用
/**
* @file
* 方案一:不使用useCallback和memo
* 方案二:只使用memo
* 方案三:使用memo和useCallback
*/
import React, { useState, useEffect, useCallback, useMemo } from 'react';
import { render } from 'react-dom';
import './index.less';
//
// const Test1 = ({ log }) => {
// useEffect(() => {
// log()
// }, [log]);
// return <div>子组件</div>;
// };
interface Test1Props {
log: () => void;
}
const Test1: React.FC<Test1Props> = React.memo(({ log }) => {
useEffect(() => {
log()
}, [log]);
return <div>子组件</div>;
});
const App = () => {
const [count, setCount] = useState(0);
const refreshPage = () => {
setCount(count + 1);
};
// const handleLog = () => {
// console.log('打点----')
// };
const handleLog = useCallback(() => {
console.log('打点----')
},[])
return <>
<div>
<h1>React Hooks整理</h1>
<button onClick={refreshPage}>全局刷新次数</button>
<div>当前刷新次数:{count}</div>
<Test1 log={handleLog} />
</div>
</>;
};
render(<App />,
document.getElementById('rooot')
);
- 方案一:不使用useCallback和memo,父组件状态的更新,会导致子组件重新渲染
- 方案二:只使用memo,父组件状态的更新,导致log函数会更新,虽然子组件使用了memo,但是子组件传参一直改变,所以并不生效,和方案一结果是一样的。
(注:与字面量对象{}总是会创建新对象类似,**在 JavaScript 中,function () {}或者() => {}总是会生成不同的函数**。) - 方案三:父组件的更新,不会导致log更新,所以子组件不会重新渲染
应用一:useCallback和useMemo区别
- useCallback:缓存函数本身
- useMemo:调用函数并缓存结果