1.8 KiB
1.8 KiB
title, impact, impactDescription, tags
| title | impact | impactDescription | tags |
|---|---|---|---|
| 拆分组合的 Hook 计算 | MEDIUM | 避免重新计算独立的步骤 | rerender, useMemo, useEffect, dependencies, optimization |
拆分组合的 Hook 计算
当一个 Hook 包含多个具有不同依赖项的独立任务时,应将它们拆分为单独的 Hook。组合式的 Hook 在任意依赖项发生变化时会重新运行所有任务,即使某些任务并未使用已变化的值。
错误(修改 sortOrder 会重新计算过滤):
const sortedProducts = useMemo(() => {
const filtered = products.filter((p) => p.category === category)
const sorted = filtered.toSorted((a, b) =>
sortOrder === "asc" ? a.price - b.price : b.price - a.price
)
return sorted
}, [products, category, sortOrder])
正确(仅当 products 或 category 变化时才重新计算过滤):
const filteredProducts = useMemo(
() => products.filter((p) => p.category === category),
[products, category]
)
const sortedProducts = useMemo(
() =>
filteredProducts.toSorted((a, b) =>
sortOrder === "asc" ? a.price - b.price : b.price - a.price
),
[filteredProducts, sortOrder]
)
此模式同样适用于组合了不相关副作用的 useEffect:
错误(任一依赖变化时两个副作用都会执行):
useEffect(() => {
analytics.trackPageView(pathname)
document.title = `${pageTitle} | My App`
}, [pathname, pageTitle])
正确(副作用独立执行):
useEffect(() => {
analytics.trackPageView(pathname)
}, [pathname])
useEffect(() => {
document.title = `${pageTitle} | My App`
}, [pageTitle])
注意: 如果你的项目启用了 React Compiler,它会自动优化依赖追踪,部分上述情况可能已自动处理。