前言
书接上文
如何避免使用 useCallback
避免 useCallback 的最佳方法是将函数移出组件范围。使用完全依赖于传入参数而不是范围内值的纯函数。
示例 1
上面示例的改进:
function FidgetSpinner() {
const [spinning, setSpinning] = useState(false)
return (
<>
<p>Is it spinning? {spinning}</p>
<Spinner spinning={spinning} setSpinning={setSpinning} />
</>
)
}
setSpinning 是一个稳定的函数!您可以将它传递给 <Spinner> , 使用它的来切换状态:
setSpinning((spinning) => !spinning)
你可以使用一个函数来调用 React setters,该函数将当前值作为参数。
示例 2
将使用局部作用域的函数转换为独立的(可测试🤘)函数。就像使用 react-hook-form 构建表单时一样
function ComplicatedStuff() {
const formMethods = useForm()
const fieldValue = formMethods.watch("field")
return (
<>
<p>Live current value of field: {fieldValue}</p>
<FormRenderComponent onSubmit={onSubmit} />
</>
)
}
formMethods.watch 监视您的输入字段并返回其当前值。当您构建动态表单时非常有用。
onSubmit 函数:
function ComplicatedStuff() {
const formMethods = useForm()
const fieldValue = formMethods.watch('field')
async function onSubmit() {
await fetch('...', {
method: 'POST',
body: JSON.stringify({
fieldValue
})
})
}
你在每次按键时都完全重新渲染💩
所以这样写:
async function onSubmit(values) {
await fetch('...', {
method: 'POST',
body: JSON.stringify({
fieldValue: values.fieldValue
})
})
}
function ComplicatedStuff() {
const formMethods = useForm()
const fieldValue = formMethods.watch('field')
React-hook-form 将所有当前值传递给 onSubmit 函数。您不需要依赖组件范围!
Cough
当然,这就是这个库的工作方式,我的观点是一般原则 👉 寻找机会重构您的函数,以便它们依赖于参数而不是作用域。
然后你可以将它们移动到任何地方。灵活性 🤩(和稳定的引用)
你什么时候需要 useCallback
如果您正在编写将在许多组件中出现的库或核心功能,请记住所有内容。
像 React Query 或 useAuth 这样的库可以让你的整个应用程序意外地重新渲染。你确实想阻止这种情况。
一个回调在 3 个小组件中共享?嗯。专注于保持快速渲染而不是担心重新渲染。
PS:现在的计算机速度很快,在我使用 React 18 的实验中,需要数千个元素才能注意到性能问题
PPS:我听说 React 团队正在开发一个自动记忆引擎来为你处理这一切🤞
全文完
谢谢!
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 20 天