React无法正常展示JSON数据,求问题排查及解决方法
React无法渲染JSON文件的问题排查与解决
问题重现
你的App.js代码:
import "./App.css"; import title from "./data/breaking.json"; export default function App() { const { data } = title return ( <div className="App"> {data} </div> ); }
你的./data/breaking.json内容(存在语法错误):
{ "pubDate":{ "5":"31-10-2022 06:26:18 UTC", "1":"31-10-2022 06:26:09 UTC", "4":"31-10-2022 06:24:07 UTC", "3":"31-10-2022 06:22:43 UTC", "8":"31-10-2022 06:21:59 UTC", "2":"31-10-2022 11:51:04 ", "7":"31-10-2022 06:20:48 UTC", "0":"31-10-2022 02:20:33 ", "9":"31-10-2022 06:20:17 UTC", "10":"31-10-2022 06:18:00 UTC" }, "timestamp":{ "5":1667197578.0, "1":1667197569.0, "4":1667197447.0, "3":1667197363.0, "8":1667197319.0, "2":1667197264.0, "7":1667197248.0, "0":1667197233.0, "9":1667197217.0, "10":1667197080.0 } // 缺少闭合的 }
错误分析
- JSON语法错误:你的JSON文件末尾缺少一个闭合的
},这会导致React无法解析该文件,直接导入失败。 - 解构错误:你从导入的
title对象中解构data字段,但你的JSON里根本没有data键,title本身就是包含pubDate和timestamp的对象,所以const { data } = title会得到undefined,渲染时页面无内容。 - 直接渲染对象:即使你拿到了
pubDate或timestamp,直接在JSX中渲染对象类型会触发React报错——React只能渲染字符串、数字、React元素等可直接渲染的类型,无法直接渲染对象。
修复方案
第一步:修复JSON语法错误
虽然你提到重新格式化成本高,但必须补全JSON末尾的},否则文件本身无效,无法被任何程序解析。修复后的JSON末尾加上}即可:
{ "pubDate":{ "5":"31-10-2022 06:26:18 UTC", "1":"31-10-2022 06:26:09 UTC", "4":"31-10-2022 06:24:07 UTC", "3":"31-10-2022 06:22:43 UTC", "8":"31-10-2022 06:21:59 UTC", "2":"31-10-2022 11:51:04 ", "7":"31-10-2022 06:20:48 UTC", "0":"31-10-2022 02:20:33 ", "9":"31-10-2022 06:20:17 UTC", "10":"31-10-2022 06:18:00 UTC" }, "timestamp":{ "5":1667197578.0, "1":1667197569.0, "4":1667197447.0, "3":1667197363.0, "8":1667197319.0, "2":1667197264.0, "7":1667197248.0, "0":1667197233.0, "9":1667197217.0, "10":1667197080.0 } }
第二步:修正React渲染逻辑
修改App.js,正确读取JSON中的字段,并将对象转换为可渲染的列表:
import "./App.css"; import breakingData from "./data/breaking.json"; export default function App() { // 直接解构JSON中的pubDate和timestamp字段 const { pubDate, timestamp } = breakingData; return ( <div className="App"> <h2>发布时间列表</h2> <ul> {/* 使用Object.entries将对象转为键值对数组,再遍历渲染 */} {Object.entries(pubDate).map(([key, date]) => ( <li key={key}> 条目{key}: {date} </li> ))} </ul> <h2>时间戳列表</h2> <ul> {Object.entries(timestamp).map(([key, ts]) => ( <li key={key}> 条目{key}: {new Date(ts * 1000).toLocaleString()} </li> ))} </ul> </div> ); }
实现实时更新
由于你的JSON文件会定期更新,静态导入的方式在生产环境无法自动获取最新内容,改用fetch定期拉取数据:
import "./App.css"; import { useState, useEffect } from "react"; export default function App() { const [breakingData, setBreakingData] = useState(null); const [loading, setLoading] = useState(true); // 定义拉取数据的函数 const fetchLatestData = async () => { try { const response = await fetch("/data/breaking.json"); const data = await response.json(); setBreakingData(data); setLoading(false); } catch (error) { console.error("获取数据失败:", error); setLoading(false); } }; // 组件挂载时拉取一次,之后每30秒刷新一次 useEffect(() => { fetchLatestData(); const interval = setInterval(fetchLatestData, 30000); // 组件卸载时清除定时器 return () => clearInterval(interval); }, []); // 加载状态处理 if (loading) return <div className="App">加载中...</div>; if (!breakingData) return <div className="App">加载失败,请稍后重试</div>; const { pubDate, timestamp } = breakingData; return ( <div className="App"> <h2>发布时间列表</h2> <ul> {Object.entries(pubDate).map(([key, date]) => ( <li key={key}> 条目{key}: {date} </li> ))} </ul> <h2>时间戳列表</h2> <ul> {Object.entries(timestamp).map(([key, ts]) => ( <li key={key}> 条目{key}: {new Date(ts * 1000).toLocaleString()} </li> ))} </ul> </div> ); }
这个方案通过定时器定期调用fetch获取最新的JSON文件,不需要重新构建项目就能实时展示更新后的内容。
内容的提问来源于stack exchange,提问作者Sreetam Ganguly
相关产品推荐
相关产品推荐

