如何在useSWR的key变化时,即使缓存存在仍显示加载状态?
解决方案
要实现用户每次修改筛选条件时都显示加载状态,同时避免轮询触发不必要的加载提示,可以通过自定义加载状态结合useSWR的回调来实现,具体步骤如下:
- 新增一个状态变量专门控制筛选触发的加载状态
- 监听筛选条件的变化,一旦变化就开启加载状态
- 利用useSWR的请求完成回调,在请求结束后关闭加载状态
修改后的代码示例
import { useState, useEffect } from 'react'; import useSWR from 'swr'; const App = () => { const [filter, setFilter] = useState({ filterText: '', showCompleted: false, }); // 自定义筛选加载状态 const [isFilterLoading, setIsFilterLoading] = useState(false); const { data, error, mutate } = useSWR( ['https://jsonplaceholder.typicode.com/todos', filter], async ([url, filter]) => { const res = await fetch(`${url}?completed=${filter.showCompleted}`); return await res.json(); }, { // 保持你的轮询配置,比如每5秒轮询 refreshInterval: 5000, // 请求成功后关闭筛选加载状态 onSuccess: () => setIsFilterLoading(false), // 请求失败后也关闭筛选加载状态 onError: () => setIsFilterLoading(false), } ); // 监听filter变化,触发加载状态 useEffect(() => { // 只有当filter变化时才开启加载 setIsFilterLoading(true); }, [filter]); // UI中使用isFilterLoading来显示加载状态 return ( <div> <label> <input type="checkbox" checked={filter.showCompleted} onChange={(e) => setFilter(prev => ({...prev, showCompleted: e.target.checked}))} /> 显示已完成 </label> {isFilterLoading && <div>加载中...</div>} {error && <div>加载失败</div>} {data && ( <ul> {data.map(item => ( <li key={item.id}>{item.title}</li> ))} </ul> )} </div> ); }; export default App;
代码说明
isFilterLoading仅在用户修改筛选条件(filter变化)时被设置为true,轮询时因为filter没有变化,不会触发这个状态更新- useSWR的
onSuccess和onError回调会在请求完成后将isFilterLoading设为false,确保加载状态只在筛选后的请求过程中显示 - 原有的
isLoading可以作为首次页面加载的状态补充,而isFilterLoading专门处理筛选触发的加载需求
内容的提问来源于stack exchange,提问作者Gnanavel
相关产品推荐
相关产品推荐

