如何在from_id变化时阻止useSWRInfinite/useSWR重新验证
解决useSWRInfinite中from_id变化时阻止自动重新验证的问题
要实现当from_id变化时(仅排除profile_id和分页页码的变化)阻止SWR自动重新验证,可以通过以下两种方案实现:
方案一:使用shouldRevalidate自定义验证逻辑
利用SWR的shouldRevalidate配置项,自定义判断是否触发重新验证的条件——仅当profile_id或分页页码变化时允许验证,from_id变化时直接阻止。
import { useSWRInfinite, useEffect, useRef } from 'swr'; const usePost = (profile_id, from_id = '') => { const PAGE_LIMIT = 5; // 保存上一次的参数值,用于对比变化 const prevProfileIdRef = useRef(profile_id); const prevFromIdRef = useRef(from_id); useEffect(() => { prevProfileIdRef.current = profile_id; prevFromIdRef.current = from_id; }, [profile_id, from_id]); const { data, size, setSize, error, mutate, isValidating } = useSWRInfinite( (pageIndex) => { const currentPageIndex = pageIndex + 1; return `/posts/profile/${profile_id}?page=${currentPageIndex}&from_id=${from_id}`; }, fetcher, { revalidateFirstPage: false, shouldRevalidate: (args) => { // 解析URL参数,对比前后变化 const parseKeyParams = (key) => { if (!key) return null; const url = new URL(key, window.location.origin); return { profile_id: url.pathname.split('/')[3], page: url.searchParams.get('page'), from_id: url.searchParams.get('from_id') || '' }; }; const currentParams = parseKeyParams(args.currentKey); const previousParams = parseKeyParams(args.previousKey); // 首次请求默认允许验证 if (!previousParams) return true; // profile_id变化时,允许重新验证 if (currentParams.profile_id !== previousParams.profile_id) { return true; } // 分页页码变化时,允许验证(正常加载下一页) if (currentParams.page !== previousParams.page) { return true; } // 仅from_id变化时,阻止重新验证 if (currentParams.from_id !== previousParams.from_id) { return false; } // 其他情况默认允许验证 return true; } }, ); // 后续逻辑... return { data, size, setSize, error, mutate, isValidating }; };
方案二:将from_id从SWR缓存Key中分离
把from_id从SWR的缓存Key中移除,仅用profile_id和分页页码作为缓存标识,同时让fetcher携带最新的from_id参数。这种方式下,from_id变化不会触发SWR的自动重新验证,若需要更新数据可手动调用mutate。
import { useSWRInfinite, useEffect } from 'swr'; const usePost = (profile_id, from_id = '') => { const PAGE_LIMIT = 5; const { data, size, setSize, error, mutate, isValidating } = useSWRInfinite( (pageIndex) => { const currentPageIndex = pageIndex + 1; // 缓存Key仅包含profile_id和页码,不包含from_id return `/posts/profile/${profile_id}?page=${currentPageIndex}`; }, // 在fetcher中拼接最新的from_id参数 (key) => fetcher(`${key}&from_id=${from_id}`), { revalidateFirstPage: false, }, ); // 可选:当from_id变化时手动触发数据更新(按需启用) useEffect(() => { mutate(); }, [from_id, mutate]); // 后续逻辑... return { data, size, setSize, error, mutate, isValidating }; };
两种方案的区别:
- 方案一严格控制SWR的自动验证触发时机,适合需要保留自动验证逻辑但排除
from_id影响的场景; - 方案二更彻底地隔离
from_id与缓存逻辑,适合from_id频繁变化但无需自动重新验证的场景。
内容的提问来源于stack exchange,提问作者Epple
相关产品推荐
相关产品推荐

