看看useCallback这个React钩子有什么用处,以及如何使用它!
如果你是新手,请先看看我的React钩子介绍。
我有时使用的一个React钩子是useCallback 。
import React, { useCallback } from 'react'
这个钩子在你有一个组件的孩子经常重新渲染的时候很有用,你给它传递一个回调。
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数据结构,并将每个函数添加到其中,来可视化这个问题。因为它只存储唯一的元素,在我们的例子中,这意味着不同的(唯一实例化的)函数。
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 = (() => {
setCount(count + 1)
})
const decrement = (() => {
setCount(count - 1)
})
const incrementOtherCounter = (() => {
setOtherCounter(otherCounter + 1)
})
你把所有这些调用包在。
const increment = useCallback(() => {
setCount(count + 1)
}, [count])
const decrement = useCallback(() => {
setCount(count - 1)
}, [count])
const incrementOtherCounter = useCallback(() => {
setOtherCounter(otherCounter + 1)
}, [otherCounter])
确保你把那个数组作为第二个参数添加到useCallback() ,并添加所需的状态。
现在,如果你试图点击其中一个计数器,只有与改变的状态相关的函数会被重新实例化。
你可以在Codepen上试试这个例子。
请看Flavio Copes(@flaviocopes)在CodePen上的PenReact useCallback钩子。