userCallback
- 实际目的是为了进行性能的优化。
如何进行性能优化? - useCallback会返回一个函数的memoized(记忆的,拼写无误)值;
- 在依赖不变的情况下,多次定义的时候,返回的值是相同的。
参数
- 回调函数;
- 依赖项:无依赖时,执行原来的函数;依赖项改变时,函数进行一个更新。
返回值 - 返回一个函数的memoized值。
一. 什么情况不能进行性能优化?
每次渲染时,我们组件中的局部变量都要重新定义一次。
const increment1 = () => {
console.log("执行increment1函数");
setCount(count + 1);
}
// 第二个参数为空数组,表示谁都不依赖;
// 没有发生更新的原因是用到了闭包;
// 函数只定义了一次,引用到外部变量最原始的初始值0。
const increment2 = useCallback(() => {
console.log("执行increment2函数");
setCount(count + 1);
}, [count])
这种情况下:
- increment1函数在重新渲染时,要创建一个新的函数,有函数的创建过程;
- increment2在重新渲染时,也有函数的重新创建过程;依然要执行useCallback后面的代码,只是返回的值相同。有函数的创建过程。
二. 如何进行性能优化?
下面例子中,show发生变化,button应该不需要重新渲染的,怎么禁掉它的重新渲染呢?
使用PureComponent或memo:进行浅层比较,有更新就渲染,没更新不渲染。
这里需要注意几点:
- 当组件重新渲染时,组件内临时变量要重新定义(increment1),意味着每次传给btn1的increment1都是一个新的函数,也意味着memo失去了作用。
- 因为increment2使用了useCallback并指定了依赖项,所有其每次返回的都是相同的值。也就意味着increment2也是相同的值,memo比较时,检测到increment2没有发生改变,就不会重新渲染。
import React, { useState, useCallback, memo } from 'react'
/**
* useCallback在什么时候使用?
* 场景:在将一个组件中的函数,传递给子元素进行回调使用时,
* 使用useCallback对函数进行处理。
*
*/
const HYButton = memo((props) => {
console.log("HYButton重新渲染:" + props.title);
return <button onClick={props.increment}>HYButton +1</button>
})
export default function CallbackHookDemo02() {
console.log("CallbackHookDemo02重新渲染");
const [count, setCount] = useState(0);
const [show, setShow] = useState(true);
const increment1 = () => {
console.log("执行increment1函数");
setCount(count + 1);
}
const increment2 = useCallback(() => {
console.log("执行increment2函数");
setCount(count + 1);
}, [count])
return (
<div>
<h2>CallbackHookDemo01:{count}</h2>
{/* <button onClick={increment1}>+1</button>
<button onClick={increment2}>+1</button> */}
<HYButton title="btn1" increment={increment1} />
<HYButton title="btn2" increment={increment2} />
<button onClick={e => setShow(!show)}>show切换</button>
</div>
)
}