如何在React+Material UI中解析API返回的复杂嵌套JSON并展示
解决方案
步骤1:解析嵌套JSON字符串
note.notes是JSON格式的字符串,需先用JSON.parse()解析为JavaScript对象,同时加入错误处理避免解析失败导致页面崩溃。
步骤2:提取并格式化文本内容
从解析后的对象中提取核心文本,处理换行符\n,并应用标记中的样式(文本颜色、背景色)。可编写辅助函数完成内容提取与样式映射。
步骤3:用Material UI组件渲染
使用Typography、Box等组件,结合提取的样式与文本内容,实现美观展示。
修改后的完整代码
import React, { useEffect, useState } from 'react'; import { Container, Typography, Card, CardContent, Grid, Box } from '@mui/material'; import axios from 'axios'; // 辅助函数:解析notes并提取带样式的内容 const parseNotesContent = (notesStr) => { try { const notesObj = JSON.parse(notesStr); // 遍历嵌套结构找到包含文本的节点 const textNode = notesObj.content?.[0]?.content?.find(block => block.content?.[0]?.content?.[0]?.type === 'text' )?.content?.[0]?.content?.[0]; if (!textNode) return null; // 提取样式参数与文本内容 const text = textNode.text; const marks = textNode.marks || []; const textColor = marks.find(m => m.type === 'textColor')?.attrs?.color || 'inherit'; const bgColor = marks.find(m => m.type === 'backgroundColor')?.attrs?.color || 'transparent'; // 拆分换行符为独立行 const textLines = text.split('\n').filter(line => line.trim() !== ''); return { textLines, textColor, bgColor }; } catch (err) { console.error('解析notes失败:', err); return null; } }; function App() { const [notes, setNotes] = useState([]); useEffect(() => { axios.get('https://api.gyanibooks.com/library/get_dummy_notes') .then((res) => { setNotes(res.data); }) .catch(err => { console.error(err); }); }, []); return ( <Container> <Typography variant="h4" gutterBottom> Notes </Typography> <Grid container spacing={2}> {notes.map((note) => { const parsedContent = parseNotesContent(note.notes); return ( <Grid item xs={12} key={note.id}> <Card> <CardContent> <Typography variant="h6" gutterBottom> {note.title} </Typography> <Typography variant="subtitle1" gutterBottom> ID: {note.id} </Typography> <Typography variant="subtitle1" gutterBottom> Category: {note.category} </Typography> <Typography variant="subtitle1" gutterBottom> User: {note.user} </Typography> {parsedContent ? ( <Box sx={{ mt: 2, color: parsedContent.textColor, backgroundColor: parsedContent.bgColor, p: 2, borderRadius: 1 }} > {parsedContent.textLines.map((line, index) => ( <Typography key={index} variant="body1" gutterBottom sx={{ whiteSpace: 'pre-line' }} > {line} </Typography> ))} </Box> ) : ( <Typography variant="body2" color="error" mt={2}> 内容解析失败 </Typography> )} </CardContent> </Card> </Grid> ); })} </Grid> </Container> ); } export default App;
代码说明
- 解析处理:
parseNotesContent函数负责JSON字符串解析,捕获解析错误避免页面崩溃;同时遍历嵌套结构提取文本与样式属性。 - 样式应用:通过Material UI的
sx属性,将提取的文本颜色、背景色应用到容器,提升内容可读性。 - 换行处理:使用
whiteSpace: 'pre-line'让\n自动转换为换行,拆分文本为独立Typography组件优化列表展示。 - 错误降级:解析失败时显示友好错误提示,保证页面可用性。
内容的提问来源于stack exchange,提问作者Aach_copro
相关产品推荐
相关产品推荐

