了解 useCallback React hook 的用途,以及如何使用它!
如果您对 React hooks 还不熟悉,请先阅读我的React hooks 介绍。
我有时会使用一个叫做 useCallback
的 React hook。
import React, { useCallback } from 'react'
当您有一个频繁重新渲染的子组件,并向其传递一个回调时,这个 hook 是很有用的:
import React, { useState, useCallback } from 'react'
const Counter = () => {
const [count, setCount] = useState(0)
const [otherCounter, setOtherCounter] = useState(0)
const increment = () => {
setCount(count + 1)
}
const decrement = () => {
setCount(count - 1)
}
const incrementOtherCounter = () => {
setOtherCounter(otherCounter + 1)
}
return (
<>
Count: {count}
<button onClick={increment}>+</button>
<button onClick={decrement}>-</button>
<button onClick={incrementOtherCounter}>incrementOtherCounter</button>
</>
)
}
ReactDOM.render(<Counter />, document.getElementById('app'))
问题在于,每次更新计数器时,这 3 个函数都会重新创建。
您可以通过实例化一个 Set 数据结构,并将每个函数添加到其中来可视化此情况。为什么使用 Set?因为它只存储唯一的元素,而在我们的情况下,这意味着不同(唯一实例化)的函数。
import React, { useState, useCallback } from 'react'
const functionsCounter = new Set()
const Counter = () => {
const [count, setCount] = useState(0)
const [otherCounter, setOtherCounter] = useState(0)
const increment = () => {
setCount(count + 1)
}
const decrement = () => {
setCount(count - 1)
}
const incrementOtherCounter = () => {
setOtherCounter(otherCounter + 1)
}
functionsCounter.add(increment)
functionsCounter.add(decrement)
functionsCounter.add(incrementOtherCounter)
alert(functionsCounter)
return (
<>
Count: {count}
<button onClick={increment}>+</button>
<button onClick={decrement}>-</button>
<button onClick={incrementOtherCounter}>incrementOtherCounter</button>
</>
)
}
ReactDOM.render(<Counter />, document.getElementById('app'))
如果您尝试运行此代码,您会看到每次警报增加 3。
相反,应该的做法是,如果您增加一个计数器,所有与该计数器相关的函数都应该被重新实例化。
如果另一个状态值没有改变,那它应该不被触及。
现在,在大多数情况下,这不是一个很大的问题,除非您传递了许多不同的函数,这些函数都会更改不相关的数据部分,这对应用的性能产生了巨大的成本。
如果遇到这个问题,您可以使用 useCallback
。
下面是使用方法。将这些调用都包装在下面的代码块中:
const increment = useCallback(() => {
setCount(count + 1)
}, [count])
const decrement = useCallback(() => {
setCount(count - 1)
}, [count])
const incrementOtherCounter = useCallback(() => {
setOtherCounter(otherCounter + 1)
}, [otherCounter])
确保将这个数组作为第二个参数传递给 useCallback()
,其中包含所需的状态。
现在,如果您尝试点击其中一个计数器,只有与更改状态相关的函数将被重新实例化。
您可以在 Codepen 上尝试此示例:
React useCallback hook by Flavio Copes (@flaviocopes)。
标签:React, React hook, useCallback