如何阻止useSWR初始化时自动请求,仅调用mutate时才触发数据拉取?
SWR 自定义 Hook 禁用初始自动请求解决方案
核心原因
你已配置的revalidateOnMount: false仅能禁用组件挂载时的强制重验证,但SWR默认开启revalidateIfStale: true配置,首次加载无缓存时会判定数据过期,自动触发初始请求,这是你遇到问题的根本原因。同时你当前使用的全局无参数mutate()会触发所有SWR缓存重验证,属于错误用法,需要修正。
方案1:补充禁用自动验证配置(最简单)
直接在useSWR的配置项中新增revalidateIfStale: false,同时改用当前Hook对应返回的mutate方法避免影响其他请求:
import useSWR, { useSWRConfig } from "swr"; export function useCars(registrationPlates: number[]): ICars { const swrKey = carsToFetchUrls(registrationPlates); const { data: carData, mutate: mutateCars } = useSWR<Car[]>( swrKey, { revalidateOnFocus: false, revalidateOnMount: false, revalidateOnReconnect: false, refreshWhenOffline: false, refreshWhenHidden: false, refreshInterval: 0, // 新增以下配置,禁用无缓存时的自动请求 revalidateIfStale: false, shouldRetryOnError: false // 可选,禁用错误自动重试,避免意外请求 } ); const getCar = (carRegistrationPlate: number): Car => { console.log(carData) // 未调用mutate前为undefined // 调用当前key对应的mutate,仅触发汽车数据的请求 void mutateCars(); // 其余逻辑 } // 导出方法 return { getCar } }
方案2:条件请求模式(最稳妥,完全避免意外请求)
通过控制SWR的key为falsy值,让SWR默认完全不初始化请求,仅在主动触发时才传入有效key:
import useSWR, { useSWRConfig } from "swr"; import { useState } from "react"; export function useCars(registrationPlates: number[]): ICars { // 控制是否发起请求的开关,默认关闭 const [enableFetch, setEnableFetch] = useState(false); const swrKey = enableFetch ? carsToFetchUrls(registrationPlates) : null; const { data: carData, mutate: mutateCars } = useSWR<Car[]>(swrKey, { revalidateOnFocus: false, revalidateOnReconnect: false, refreshWhenOffline: false, refreshWhenHidden: false, refreshInterval: 0, }); const getCar = (carRegistrationPlate: number): Car => { // 首次调用时开启请求开关 if(!enableFetch) setEnableFetch(true); // 触发请求 void mutateCars(); // 其余逻辑 } return { getCar } }
这个方案的优势是只要enableFetch为false,SWR绝对不会发起任何请求,完全杜绝意外触发的可能性,适合对请求触发时机要求严格的场景。
内容的提问来源于stack exchange,提问作者DLO
相关产品推荐
相关产品推荐

