React项目如何实现API优先、本地JSON fallback的数据获取方案?
实现API降级到本地JSON的useFetch Hook修改方案
1. 基础版本:固定本地JSON降级逻辑
直接在现有useFetch Hook的请求失败分支中,切换到本地JSON数据。假设你已经有统一的db.json文件:
import { useState, useEffect } from 'react'; // 提前导入本地JSON文件 import localBackupData from './db.json'; export const useFetch = (apiUrl) => { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { const fetchResource = async () => { setLoading(true); try { const response = await fetch(apiUrl); if (!response.ok) throw new Error('API请求失败'); const apiData = await response.json(); setData(apiData); setError(null); } catch (err) { // API不可用时,直接使用本地备份数据 setData(localBackupData); setError('API暂时不可用,已加载本地缓存数据'); console.warn('API请求失败,切换到本地数据:', err.message); } finally { setLoading(false); } }; fetchResource(); }, [apiUrl]); return { data, loading, error }; };
核心要点
- 本地JSON文件需与API返回的数据结构完全一致,确保页面渲染逻辑无需修改
- 失败分支同时设置错误提示,方便开发调试和用户感知
2. 进阶版本:页面级独立本地数据
如果Home和Logement页面需要不同的本地备份文件,可以给Hook增加本地路径参数,实现动态导入:
import { useState, useEffect } from 'react'; export const useFetch = (apiUrl, localDataPath) => { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { const fetchResource = async () => { setLoading(true); try { const response = await fetch(apiUrl); if (!response.ok) throw new Error('API响应异常'); const apiData = await response.json(); setData(apiData); setError(null); } catch (apiErr) { // 尝试加载对应页面的本地数据 try { const localModule = await import(localDataPath); setData(localModule.default); setError('API不可用,已加载本地数据'); } catch (localErr) { setError('API和本地数据均加载失败'); console.error('本地数据加载失败:', localErr.message); } } finally { setLoading(false); } }; fetchResource(); }, [apiUrl, localDataPath]); return { data, loading, error }; };
页面中调用示例
// Home页面 const { data, loading, error } = useFetch('/api/home/list', './home-local.json'); // Logement页面 const { data, loading, error } = useFetch('/api/logement/detail', './logement-local.json');
3. 页面状态处理
在页面中根据返回的状态做基础交互:
function Home() { const { data, loading, error } = useFetch('/api/home', './db.json'); if (loading) return <div>加载中...</div>; if (error) return <div className="error-notice">{error}</div>; return ( <div className="home-container"> {/* 基于data渲染页面内容,逻辑无需修改 */} </div> ); }
注意事项
- 本地JSON文件需放在项目可访问目录下,确保打包工具(如Vite/Webpack)能正确识别
- 测试API降级场景时,可通过修改API地址为无效值、断开网络等方式验证逻辑
- 若API返回数据有动态更新需求,可考虑在API恢复后自动刷新数据(需额外增加监听逻辑)
内容的提问来源于stack exchange,提问作者Heighties
相关产品推荐
相关产品推荐

