如何为React组件的请求添加缓存,避免重复请求相同参数的资源
实现方案
核心思路是额外维护一个缓存结构存储已经请求过的index和对应的数据,每次请求前先检查缓存,命中则直接使用缓存数据,未命中再发起请求,请求成功后将结果写入缓存。
方案1:组件实例独享缓存
仅当前组件实例可以复用缓存,适合不需要跨组件共享数据的场景,用useRef存储缓存对象(useRef的内容不会随组件重渲染重置)。
改造后代码:
import { useState, useEffect, useRef } from 'react'; function MyComponent({ index }) { const [data, setData] = useState(''); // 用Map作为缓存结构,key为index,value为对应请求结果 const requestCache = useRef(new Map()); useEffect(() => { // 缓存命中直接赋值,跳过请求 if (requestCache.current.has(index)) { setData(requestCache.current.get(index)); return; } // 标记位,避免竞态问题:index快速切换时旧请求返回后覆盖新数据 let isActive = true; (async function() { const result = await fetchData(index); if (isActive) { setData(result); // 请求成功后写入缓存 requestCache.current.set(index, result); } })(); // 组件卸载/ index变化时触发清理,标记当前请求无效 return () => { isActive = false; }; }, [index]); return <h1>{data}</h1>; }
方案2:多实例全局共享缓存
如果有多个MyComponent实例需要复用同一份缓存数据,可以把缓存对象提到组件外部,所有实例都读写同一个缓存结构。
改造后代码:
import { useState, useEffect } from 'react'; // 全局缓存,所有MyComponent实例共享 const GLOBAL_REQUEST_CACHE = new Map(); function MyComponent({ index }) { const [data, setData] = useState(''); useEffect(() => { if (GLOBAL_REQUEST_CACHE.has(index)) { setData(GLOBAL_REQUEST_CACHE.get(index)); return; } let isActive = true; (async function() { const result = await fetchData(index); if (isActive) { setData(result); GLOBAL_REQUEST_CACHE.set(index, result); } })(); return () => { isActive = false; }; }, [index]); return <h1>{data}</h1>; }
扩展优化点
- 可以在存储缓存时同时记录时间戳,查询缓存时判断是否超过有效期,实现自动过期清理
- 如果缓存key是复杂对象,可以序列化后作为Map的key
- 缓存条目较多时可以加入LRU淘汰逻辑,避免内存占用过高
内容的提问来源于stack exchange,提问作者Vic
相关产品推荐
相关产品推荐

