
本文详解 react 中安全获取、解析和渲染 json 数据的最佳实践,包括状态管理、数据结构转换、条件渲染及常见错误规避。
在 React 应用中处理来自 REST API 的 JSON 数据时,仅调用 res.json() 并直接 console.log 是远远不够的——真正关键的是结构化地提取、安全地存储、健壮地渲染所需字段(如 origin、destination、price)。你提供的原始代码存在多个典型问题:使用普通数组 datos.push() 而非 useState 状态更新、未解构嵌套数据、缺少加载/错误状态、且直接 JSON.stringify(datos) 无法实现语义化展示。
以下是推荐的完整解决方案(含关键改进说明):
✅ 正确做法:使用 useState + 解构 + 映射渲染
import { useState, useEffect } from 'react';
function FlightList() {
const [datos, setDatos] = useState([]); // ✅ 使用 useState 管理响应数据
const [loading, setLoading] = useState(true); // ✅ 添加加载状态
const [error, setError] = useState(null); // ✅ 添加错误状态
useEffect(() => {
const fetchData = async () => {
try {
setLoading(true);
const response = await fetch(url, options);
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const json = await response.json();
// ✅ 安全解构:检查 success 和 data 是否存在
if (!json.success || !json.data) {
throw new Error('Invalid API response: missing success flag or data');
}
// ✅ 提取目标字段:遍历 data 对象的每个日期键,构造精简数组
const dataList = Object.entries(json.data).map(([date, flight]) => ({
date, // 可选:保留日期作为上下文
origin: flight.origin,
destination: flight.destination,
price: flight.price,
}));
setDatos(dataList);
} catch (err) {
console.error('Fetch error:', err);
setError(err.message);
} finally {
setLoading(false);
}
};
fetchData();
}, []);
// ✅ 条件渲染:避免空数据或 loading 时渲染无效内容
if (loading) return Loading flights...;
if (error) return Error: {error};
return (
{datos.length === 0 ? (
No flights available.
) : (
datos.map((flight, index) => (
{flight.origin} → {flight.destination}
Price: €{flight.price}
Date: {flight.date}
))
)}
);
}
export default FlightList;? 关键要点说明:
- 永远用 setState 更新 UI:datos.push(...) 修改的是普通数组,不会触发重渲染;必须使用 setDatos([...])。
- 解构优于链式访问:json.data['2023-02-08'].origin 易因键不存在而报错;Object.entries(json.data) + 解构更安全、可读性更强。
- 添加加载与错误边界:提升用户体验与调试效率,避免白屏或 undefined 渲染。
- 使用 key 保证列表稳定性:若数据有唯一 ID(如 flight_number),优先用它代替 index(尤其当列表可能排序/过滤时)。
-
类型提示(进阶建议):配合 TypeScript 定义接口,如:
interface Flight { date: string; origin: string; destination: string; price: number; } const [datos, setDatos] = useState([]);
遵循以上模式,你不仅能精准提取 origin/destination/price,还能构建出可维护、可测试、用户友好的数据驱动组件。










