You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何利用SWR Hook缓存数据并避免自动重复请求

解决SWR缓存复用与无效请求问题

我来帮你梳理下问题并给出针对性的解决方案,你的核心需求有两个:一是重新导航到组件时复用SWR缓存、避免重复请求;二是彻底阻止SWR的自动重发请求,消除无效的404请求。咱们一步步调整你的代码:

核心问题分析

你之前的代码有两个关键误区:

  1. 错误地将SWR的配置项(比如revalidateOnFocus)放到了parameters状态中,这些配置应该作为useSWR的第三个参数传入,而非请求Key的一部分;
  2. mounted状态切换请求Key为null的逻辑,会导致SWR频繁触发无效请求,同时也不利于缓存匹配。

修改后的完整代码

const CategoryList = ({ setLoading }) => { 
  const [category, setCategory] = useState(''); 
  const company_id = localStorage.getItem('company_id'); 
  const session = new SessionService(); 

  // 定义稳定的请求Key:仅当company_id存在时生成有效URL,确保导航回来时能匹配缓存
  const swrKey = company_id ? `${session.domain}/company/${company_id}/category-stats` : null;

  const { data: dataFromFetch, error } = useSWR(swrKey, 
    (url) => session.fetch(url, { method: 'GET' }), 
    { 
      // 彻底禁用所有自动重验证行为
      revalidateOnFocus: false,
      revalidateOnMount: false,  // 挂载时直接用缓存,不发起新请求
      revalidateOnReconnect: false,
      refreshWhenOffline: false,
      refreshWhenHidden: false,
      refreshInterval: 0,  // 关闭定时刷新
      
      onSuccess: (data) => { 
        setCategory(data); 
        setLoading(false); 
      }, 
      onError: (err) => { 
        console.log("error", err);
        setLoading(false); 
      } 
    } 
  ); 

  // 组件挂载时初始化loading状态
  useEffect(() => {
    setLoading(true);
    // 若已有缓存,SWR会直接返回缓存数据;若无缓存则自动发起请求
  }, []);

  return ( 
    <div className={classes.CategoryList}> 
      <h5>Parc de véhicules</h5> 
      <div className={classes.CategoriesCards}> 
        {category.data ? category.data.map((element, index) => (
          <CategoryItem 
            category={element.data.name} 
            carNumber={element.stats.nb_vehicles} 
            locating={element.stats.nb_booked} 
            available={element.stats.nb_available} 
            blocked={element.stats.nb_unavailable} 
            percentage={(element.stats.nb_booked / element.stats.nb_vehicles * 100).toFixed(2)} 
            key={index} 
          />
        )) : null} 
      </div> 
    </div> 
  ); 
};
export default CategoryList;

关键改动说明

  1. 稳定的请求Key
    company_id判断生成有效URL,避免了之前mounted状态导致Key频繁切换为null的问题,确保SWR能准确匹配缓存,导航回组件时直接复用缓存数据。

  2. 正确配置SWR的自动行为
    把所有自动重验证相关的配置项设为false,并将refreshInterval设为0,彻底阻止SWR定时发起请求或在页面聚焦/重连时自动刷新。

  3. 简化状态管理
    移除了不必要的mountedparameters状态,改用SWR的onSuccess/onError钩子统一管理loading状态,逻辑更清晰。

  4. 主动刷新的扩展方案
    如果之后需要主动刷新数据(比如用户手动触发),可以引入useSWRConfigmutate函数:

    import { useSWRConfig } from 'swr';
    
    // 在组件内添加
    const { mutate } = useSWRConfig();
    
    // 需要刷新时调用
    const handleRefresh = () => {
      mutate(swrKey); // 主动发起请求并更新缓存
    };
    

内容的提问来源于stack exchange,提问作者Peyo33

火山引擎 最新活动