如何使用 useCallback React hook
了解 useCallback React hook 的用途,以及如何使用它!
如果您对 React hooks 还不熟悉,请先阅读我的React hooks 介绍。
我有时会使用一个叫做 useCallback
的 React hook。
1
| import React, { useCallback } from 'react'
|
当您有一个频繁重新渲染的子组件,并向其传递一个回调时,这个 hook 是很有用的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| 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?因为它只存储唯一的元素,而在我们的情况下,这意味着不同(唯一实例化)的函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| 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
。
下面是使用方法。将这些调用都包装在下面的代码块中:
1 2 3 4 5 6 7 8 9
| 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