如何实现基于对象结构渲染数据的可复用InfoBlock组件
可复用InfoBlock组件:映射data与预设配置渲染指定项
核心实现思路
要实现仅渲染data中存在的项,你可以通过遍历data对象的键,匹配INFO_BLOCK_ITEMS中的配置,动态生成列表项:
- 提取data的所有键,过滤出在
INFO_BLOCK_ITEMS中存在的项(避免无效键) - 对每个有效键,从配置中取出标签、图标,从data中取出对应值
- 按照目标结构渲染每个列表项
完整代码实现
import React from "react"; import { Stack, Typography } from "@mui/material"; // 导入所有需要的图标组件 import AccountTreeIcon from "@mui/icons-material/AccountTree"; import FaceRetouchingNaturalIcon from "@mui/icons-material/FaceRetouchingNatural"; import InsertDriveFileOutlinedIcon from "@mui/icons-material/InsertDriveFileOutlined"; import ScheduleOutlinedIcon from "@mui/icons-material/ScheduleOutlined"; import AcUnitIcon from "@mui/icons-material/AcUnit"; const INFO_BLOCK_ITEMS = { author: { label: "Author", icon: AccountTreeIcon }, date: { label: "Created", icon: FaceRetouchingNaturalIcon }, rawMedias: { label: "RAW Medias", icon: InsertDriveFileOutlinedIcon }, face: { label: "Faces", icon: ScheduleOutlinedIcon, faceAction: true, }, s3Source: { label: "S3 Source", icon: AcUnitIcon } }; interface InfoBlockProps { data: Record<string, any>; type: string; } const InfoBlock: React.FC<InfoBlockProps> = ({ data }) => { // 处理时间戳转可读日期的工具函数 const formatDate = (timestamp: number) => { return new Date(timestamp * 1000).toLocaleString(); }; return ( <Stack spacing={2}> {/* 遍历data的键,生成列表项 */} {Object.keys(data).map((key) => { // 跳过INFO_BLOCK_ITEMS中不存在的键(可选,根据需求调整) if (!INFO_BLOCK_ITEMS[key]) return null; const { label, icon: Icon } = INFO_BLOCK_ITEMS[key]; let value = data[key]; // 针对日期类型做格式转换 if (key === "date") { value = formatDate(value); } // 可选:过滤空值项(比如face为空字符串时不渲染) // if (!value) return null; return ( <Stack key={key} direction="row" alignItems="center" spacing={1}> <Icon /> <Stack> <Typography variant="caption" color="textSecondary"> {label} </Typography> <Typography variant="body2">{value}</Typography> </Stack> </Stack> ); })} </Stack> ); }; // 使用示例 const DATASET = { author: "extrauser@site.com", date: 1669208819, rawMedias: "Video name 1, Video name 2, Video name 3", face: "" }; export default function App() { return <InfoBlock data={DATASET} type={"dataset"} />; }
关键细节说明
- 动态渲染图标:从配置中取出的是图标组件类,需要用
<Icon />的方式实例化渲染 - 数据格式处理:针对时间戳这类特殊数据,添加工具函数转换为可读格式
- 灵活性扩展:可以根据需求添加空值过滤、不同type的差异化处理逻辑
- 键的匹配校验:通过
!INFO_BLOCK_ITEMS[key]跳过无效键,避免渲染错误
内容的提问来源于stack exchange,提问作者qweezz
相关产品推荐
相关产品推荐

