React缓存Fetch结果:仅购物车新增商品时重新请求OpenAI生成菜谱
解决方案
核心思路是记录上次发起请求时的购物车商品状态,点击按钮时先对比当前商品与上次的状态是否一致:一致则直接展示缓存结果,不一致才发起新的API请求。
步骤1:添加缓存相关状态
先在组件中新增两个状态变量,分别存储上次请求的商品特征值和缓存的菜谱结果:
const [lastProductsHash, setLastProductsHash] = useState(""); const [cachedResult, setCachedResult] = useState("");
步骤2:修改点击事件函数
更新handleClicked函数,加入商品状态对比逻辑,避免重复请求:
const handleClicked = async (event) => { event.preventDefault(); // 生成当前购物车商品的唯一标识字符串(用标题拼接,保证相同商品组合结果一致) const currentProductsList = cartItems.products.map(prod => prod.title).join(" "); // 对比当前商品与上次请求的商品,一致则直接用缓存结果打开模态框 if (currentProductsList === lastProductsHash && cachedResult) { setResult(cachedResult); openModal(); return; } try { setLoading(true); setDisplayedMessage("Recipe is generating.."); const res = await fetch("API_CALL", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ prompt: `Generate recipe with this items ${currentProductsList}` }) }); const { response: data } = await res.json(); const trimmedData = data.trimStart(); if (!trimmedData) { throw new Error("Empty recipe response received"); } // 请求成功后更新缓存和上次商品标识 setCachedResult(trimmedData); setLastProductsHash(currentProductsList); setResult(trimmedData); setDisplayedMessage(""); openModal(); } catch (e) { console.error("Failed to generate recipe:", e); setDisplayedMessage("Failed to generate recipe, please try again."); } finally { // 无论请求成功失败,都重置加载状态 setLoading(false); } };
关键细节说明
- 用
map+join生成商品列表字符串,比forEach拼接更简洁高效,且能保证相同商品组合生成的字符串完全一致 - 对比逻辑放在请求前,避免不必要的API调用
- 新增
finally块确保加载状态一定会被重置,防止页面一直显示加载中 - 优化错误判断逻辑,避免空结果导致的异常
内容的提问来源于stack exchange,提问作者Rinael
相关产品推荐
相关产品推荐

