如何存储接口数据至变量,阻止初始加载后重复接收并解决数据顺序变动问题
解决重复调用接口及数据顺序随机问题
这里给你两个简单易懂的实现方案,直接解决你的问题:
方案一:localStorage持久化+数据排序(页面刷新后仍保留缓存)
这个方案会把接口数据存在浏览器本地,只有第一次加载或缓存不存在时才调用接口,同时给数据排序保证展示顺序稳定。
示例代码
import { useState, useEffect } from 'react'; const KitchenList = () => { // 初始化state,优先从localStorage取缓存数据 const [kitchens, setKitchens] = useState(() => { const saved = localStorage.getItem('kitchenList'); return saved ? JSON.parse(saved) : []; }); useEffect(() => { // 只有当缓存为空时才调用接口 if (kitchens.length === 0) { const fetchKitchens = async () => { try { const response = await fetch('你的接口地址'); const resData = await response.json(); // 对数据排序,比如按_id排序,保证顺序稳定 const sortedKitchens = resData.data.sort((a, b) => { return a._id.localeCompare(b._id); }); // 更新state并存入localStorage setKitchens(sortedKitchens); localStorage.setItem('kitchenList', JSON.stringify(sortedKitchens)); } catch (error) { console.error('获取厨房列表失败:', error); } }; fetchKitchens(); } }, [kitchens.length]); // 依赖项设为数组长度,只有为空时触发 return ( <div> {kitchens.map(kitchen => ( <div key={kitchen._id} className="kitchen-item"> <img src={kitchen.image} alt={kitchen.kitchenName} /> <h3>{kitchen.kitchenName}</h3> </div> ))} </div> ); }; export default KitchenList;
关键说明
- 初始化state时从
localStorage读取缓存,避免每次进入页面都重新请求 useEffect里加判断:只有当kitchens为空时才调用接口- 拿到接口数据后强制排序(这里用
_id排序,你也可以换成kitchenName),解决返回顺序随机的问题 - 把排序后的数据存入
localStorage,下次进入页面直接用缓存
方案二:useRef缓存(仅组件生命周期内保留缓存,页面刷新后会重新请求)
如果不需要页面刷新后保留数据,只想在组件挂载时请求一次,后续离开再返回不再请求,可以用useRef缓存数据:
示例代码
import { useState, useEffect, useRef } from 'react'; const KitchenList = () => { const [kitchens, setKitchens] = useState([]); // 用useRef标记是否已经请求过数据 const hasFetched = useRef(false); useEffect(() => { // 只有没请求过的时候才调用接口 if (!hasFetched.current) { const fetchKitchens = async () => { try { const response = await fetch('你的接口地址'); const resData = await response.json(); // 排序保证顺序稳定 const sortedKitchens = resData.data.sort((a, b) => { return a._id.localeCompare(b._id); }); setKitchens(sortedKitchens); // 标记为已请求 hasFetched.current = true; } catch (error) { console.error('获取厨房列表失败:', error); } }; fetchKitchens(); } }, []); // 空依赖项,仅组件挂载时触发一次 return ( <div> {kitchens.map(kitchen => ( <div key={kitchen._id} className="kitchen-item"> <img src={kitchen.image} alt={kitchen.kitchenName} /> <h3>{kitchen.kitchenName}</h3> </div> ))} </div> ); }; export default KitchenList;
关键说明
useRef的current属性不会随组件重新渲染而重置,用来记录是否已经请求过数据useEffect用空依赖数组,只在组件第一次挂载时执行- 同样对接口返回的数据排序,解决顺序随机问题
内容的提问来源于stack exchange,提问作者Olaoluwa Anigboro-Napoleon
相关产品推荐
相关产品推荐

