开源 我在 Gitroom 源代码中找到了一种使用 useCallback
在 useSWR
中缓存获取器的方法。
上述图片来自 platform-analytics/render.analytics.tsx
。让我们尝试理解这段代码片段。
我们将探索如何在您的 React 应用程序中使用 useCallback
钩子与 useSWR
结合来优化数据获取。我们将分解提供的代码片段,并解释为什么缓存您的获取器函数很重要。
理解代码 让我们逐步深入代码:
const load = useCallback(async () => { setLoading(true); const load = ( await fetch(`/analytics/${integration.id}?date=${date}`) ).json(); setLoading(false); return load; }, [integration, date]);
在这里,我们在 useCallback
钩子内定义了一个异步函数 load
。这个函数从指定的端点获取数据并处理加载状态。useCallback
钩子确保这个函数被记忆化,并且仅在依赖项(integration
和 date
)更改时重新创建。
接下来,我们使用 useSWR
来管理数据获取:
const { data } = useSWR(`/analytics-${integration?.id}-${date}`, load, { refreshInterval: 0, refreshWhenHidden: false, revalidateOnFocus: false, revalidateOnReconnect: false, revalidateIfStale: false, refreshWhenOffline: false, revalidateOnMount: true, });
在这里,useSWR
配置了一个键(/analytics-${integration?.id}-${date}
)和我们记忆化的 load
函数。配置选项控制数据的重新验证行为。
useCallback
如何防止不必要的重新获取 要理解 useCallback
如何防止不必要的重新获取,我们需要深入研究 React 如何处理函数引用以及 useSWR
的工作原理。
React 中的函数引用 在 React 中,每次组件重新渲染时,其中定义的所有函数都会重新创建。这意味着如果没有 useCallback
,每次渲染都会创建一个新的 load
函数实例。
对 useSWR
的影响 useSWR
是用于 React 的数据获取库。它使用一个键来标识数据和一个获取器函数来获取它。useSWR
依赖于获取器函数引用的稳定性。如果引用发生更改,useSWR
可能会将其解释为数据需要重新获取的信号,即使获取器的实际逻辑没有更改。
以下是详细解释:
没有 useCallback
:
const load = async () => { setLoading(true); const load = ( await fetch(`/analytics/${integration.id}?date=${date}`) ).json(); setLoading(false); return load; }; const { data } = useSWR(`/analytics-${integration?.id}-${date}`, load, { refreshInterval: 0, refreshWhenHidden: false, revalidateOnFocus: false, revalidateOnReconnect: false, revalidateIfStale: false, refreshWhenOffline: false, revalidateOnMount: true, });
在这种情况下,每次渲染都会创建一个新的 load
函数。useSWR
每次都会看到不同的函数引用,这可能导致即使 integration
和 date
没有更改也会进行不必要的重新获取。
使用 useCallback
:
const load = useCallback(async () => { setLoading(true); const load = ( await fetch(`/analytics/${integration.id}?date=${date}`) ).json(); setLoading(false); return load; }, [integration, date]); const { data } = useSWR(`/analytics-${integration?.id}-${date}`, load, { refreshInterval: 0, refreshWhenHidden: false, revalidateOnFocus: false, revalidateOnReconnect: false, revalidateIfStale: false, refreshWhenOffline: false, revalidateOnMount: true, });
通过将 load
函数包装在 useCallback
中,我们确保只有在其依赖项(integration
和 date
)更改时才会重新创建。函数引用的这种稳定性告诉 useSWR
,除非 integration
或 date
更改,否则获取器函数没有更改,从而防止不必要的重新获取。