Material UI嵌套Dialog含Table无法渲染问题咨询
实现嵌套Dialog+Table的购物篮详情组件方案
嘿,我刚好做过类似的嵌套弹窗需求,给你分享下我的实现思路和代码示例,应该能直接复用或者调整后用在你的项目里!
核心实现思路
- 用两个状态分别控制主全屏Dialog和子非全屏Dialog的显示/隐藏
- 给主Table每行的按钮绑定点击事件,点击时把当前行的商品数据存到状态里,同时打开子Dialog
- 子Dialog根据存储的选中商品数据,渲染对应的详情Table
代码示例(以React + Material-UI为例)
我这里用了MUI的组件,你如果用其他UI库,只要替换对应的组件就行,逻辑是通用的:
import React, { useState } from 'react'; import { Dialog, DialogContent, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Button, Paper } from '@mui/material'; // 模拟购物篮数据 const basketData = [ { id: 1, total: 3, itemName: "商品A", date: "2024-05-20", details: [ { id: 101, name: "商品A-1", price: 10, count: 1 }, { id: 102, name: "商品A-2", price: 15, count: 2 } ] }, // 可添加更多测试数据 ]; const BasketDialog = () => { // 控制主全屏Dialog的显示 const [openMain, setOpenMain] = useState(true); // 控制子Dialog的显示 const [openSub, setOpenSub] = useState(false); // 存储选中的商品详情 const [selectedItem, setSelectedItem] = useState(null); // 打开子Dialog并传入当前商品数据 const handleOpenSubDialog = (item) => { setSelectedItem(item); setOpenSub(true); }; // 关闭子Dialog const handleCloseSubDialog = () => { setOpenSub(false); setSelectedItem(null); }; return ( <> {/* 主全屏Dialog */} <Dialog open={openMain} fullScreen onClose={() => setOpenMain(false)} > <DialogContent> <h2>购物篮</h2> <TableContainer component={Paper}> <Table> <TableHead> <TableRow> <TableCell>总计</TableCell> <TableCell>商品</TableCell> <TableCell>日期</TableCell> <TableCell>操作</TableCell> </TableRow> </TableHead> <TableBody> {basketData.map(item => ( <TableRow key={item.id}> <TableCell>{item.total}</TableCell> <TableCell>{item.itemName}</TableCell> <TableCell>{item.date}</TableCell> <TableCell> <Button variant="contained" onClick={() => handleOpenSubDialog(item)} > 查看详情 [1] </Button> </TableCell> </TableRow> ))} </TableBody> </Table> </TableContainer> </DialogContent> </Dialog> {/* 子非全屏Dialog */} <Dialog open={openSub} onClose={handleCloseSubDialog} maxWidth="md" fullWidth > <DialogContent> <h3>{selectedItem?.itemName} 详情</h3> <TableContainer component={Paper}> <Table> <TableHead> <TableRow> <TableCell>商品名称</TableCell> <TableCell>单价</TableCell> <TableCell>数量</TableCell> </TableRow> </TableHead> <TableBody> {selectedItem?.details.map(detail => ( <TableRow key={detail.id}> <TableCell>{detail.name}</TableCell> <TableCell>{detail.price}</TableCell> <TableCell>{detail.count}</TableCell> </TableRow> ))} </TableBody> </Table> </TableContainer> </DialogContent> </Dialog> </> ); }; export default BasketDialog;
关键注意点
- 打开子Dialog时一定要把当前行的数据传递进去,这样子Dialog才能知道要渲染什么内容
- 记得在关闭子Dialog时清空
selectedItem状态,避免下次打开时显示旧数据 - 如果你的商品详情数据是异步获取的,可以把
handleOpenSubDialog里改成调用接口,拿到数据后再打开子Dialog
内容的提问来源于stack exchange,提问作者Claim
相关产品推荐
相关产品推荐

