我有一个 React 应用程序,它使用 SWR + Axios 进行数据获取(https://swr.vercel.app/docs/data-fetching)。问题是,我使用的自定义挂钩useSwr在初始化挂钩时最初会获取所有数据。我的目标是仅在调用时才获取mutate。目前,即使没有调用,初始提取也会发生mutate。关于如何实现我的目标有什么建议吗?
我的应用程序包含在 SWRConfig 中:
<SWRConfig
value={{
fetcher,
}}
>
<App/>
</SWRConfig>
Run Code Online (Sandbox Code Playgroud)
fetcher 的描述如下:
const dataFetch = (url) => axios.get(url).then((res) => res.data);
function fetcher(...urls: string[]) {
if (urls.length > 1) {
return Promise.all(urls.map(dataFetch));
}
return dataFetch(urls);
}
Run Code Online (Sandbox Code Playgroud)
我的自定义钩子使用useSwr
import useSWR, { useSWRConfig } from "swr";
export function useCars(registrationPlates: number[]): ICars {
const { mutate } = useSWRConfig();
const { data: carData} = useSWR<Car[]>(
carsToFetchUrls(registrationPlates), // returns string array with urls to fetch
{
revalidateOnFocus: false,
revalidateOnMount: false,
revalidateOnReconnect: false,
refreshWhenOffline: false,
refreshWhenHidden: false,
refreshInterval: 0,
}
);
const getCar = (
carRegistrationPlate: number,
): Car => {
console.log(carData) // carData contains data from fetch even before calling mutate()
void mutate();
...
}
Run Code Online (Sandbox Code Playgroud)
用法:(这将位于某个想要使用useCars钩子的组件中)
const { getCar } = useCars(carsRegistrationPlates);
Run Code Online (Sandbox Code Playgroud)
您可以在调用中使用条件提取useSWR来阻止它发出请求。
来自useSWR 条件获取文档:
使用
null或传递函数 askey有条件地获取数据。如果函数抛出或返回错误值,SWR 将不会启动请求。
export function useCars(registrationPlates: number[], shouldFetch): ICars {
const { data: carData} = useSWR<Car[]>(
shouldFetch ? carsToFetchUrls(registrationPlates) : null,
{ // Options here }
);
// ...
return { carData, /**/ }
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以按如下方式使用它以避免发出初始请求。
const [shouldFetch, setShouldFetch] = useState(false);
const { carData } = useCars(carsRegistrationPlates, shouldFetch);
Run Code Online (Sandbox Code Playgroud)
然后,当您想要发出请求时,只需将其设置shouldFetch为 true 即可。
setShouldFetch(true)
Run Code Online (Sandbox Code Playgroud)
这是实现您希望实现的目标的一种可能方法。我在我的一个生产应用程序中使用了类似的方法。首先创建一个自定义 swr 挂钩
const useCars = (registrationPlates: number[]) => {
const fetcher = (_: string) => {
console.log("swr-key=", _);
return dataFetch(registrationPlates);
};
const { data, error, isValidating, revalidate, mutate } = useSWR(`api/car/registration/${JSON.stringify(registrationPlates)}`, fetcher, {
revalidateOnFocus: false,
});
return {
data,
error,
isLoading: !data && !error,
isValidating,
revalidate,
mutate,
};
};
export { useCars };
Run Code Online (Sandbox Code Playgroud)
现在,您可以从任何其他组件调用此挂钩,如下所示
const { data, error, isLoading, isValidating, revalidate, mutate } = useCars(carsRegistrationPlates);
Run Code Online (Sandbox Code Playgroud)
现在,您可以控制传递给useCars上面的内容返回的内容。注意我们的自定义 swr 钩子中传递给第一个参数的内容useSwr,这是 swr 用于缓存值的键,如果它保持不变,那么 swr 将透明地返回缓存的值。
此外,通过此自定义挂钩,您可以获得加载、错误等状态,因此您可以对使用组件中的每个状态采取适当的操作。
| 归档时间: |
|
| 查看次数: |
9503 次 |
| 最近记录: |