如何给React Material UI DataGrid添加行点击跳转详情页功能?
实现DataGrid行点击跳转详情页的方案
要实现点击DataGrid行跳转到对应详情页的功能,你可以按照以下步骤操作:
1. 安装并配置React Router
单页应用的页面跳转依赖React Router,先安装依赖:
npm install react-router-dom # 或使用yarn yarn add react-router-dom
然后在路由配置文件(比如App.js)中添加列表页和详情页的路由规则:
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; import Reworks from './path/to/Reworks'; // 替换为你的Reworks组件实际路径 import ReworkDetail from './path/to/ReworkDetail'; // 后续要创建的详情页组件 function App() { return ( <Router> <Routes> <Route path="/reworks" element={<Reworks />} /> <Route path="/reworks/:id" element={<ReworkDetail />} /> </Routes> </Router> ); } export default App;
2. 修改Reworks组件,添加行点击跳转逻辑
在你的Reworks组件中,导入useNavigate钩子并添加行点击事件处理函数:
import { Box } from "@mui/material"; import { DataGrid, GridToolbar } from "@mui/x-data-grid"; import { tokens } from "../../theme"; import { mockDatareworks } from "../../data/mockData"; import Header from "../../components/Header"; import { useTheme } from "@mui/material"; // 新增:导入路由导航钩子 import { useNavigate } from 'react-router-dom'; const Reworks = () => { const theme = useTheme(); const colors = tokens(theme.palette.mode); // 新增:初始化导航函数 const navigate = useNavigate(); // 新增:行点击事件处理 const handleRowClick = (params) => { // 跳转到对应id的详情页 navigate(`/reworks/${params.row.id}`); }; const columns = [ { field: "id", headerName: "ID", flex: 0.5 }, { field: "return_date", headerName: "Date" }, { field: "customer_name", headerName: "Customer", flex: 1, cellClassName: "name-column--cell", }, { field: "product_name", headerName: 'Product', flex: 1, }, { field: "rework_quantity", headerName: "Quantity", type: "number", headerAlign: "left", align: "left", }, ]; return ( <Box m="20px"> <Header title="Rework" subtitle="List of reworks for Future Reference" /> <Box m="40px 0 0 0" height="75vh" sx={{ "& .MuiDataGrid-root": { border: "none", }, "& .MuiDataGrid-cell": { borderBottom: "none", }, "& .name-column--cell": { color: colors.greenAccent[300], }, "& .MuiDataGrid-columnHeaders": { backgroundColor: colors.blueAccent[700], borderBottom: "none", }, "& .MuiDataGrid-virtualScroller": { backgroundColor: colors.primary[400], }, "& .MuiDataGrid-footerContainer": { borderTop: "none", backgroundColor: colors.blueAccent[700], }, "& .MuiCheckbox-root": { color: `${colors.greenAccent[200]} !important`, }, "& .MuiDataGrid-toolbarContainer .MuiButton-text": { color: `${colors.grey[100]} !important`, }, // 可选:让行显示可点击的鼠标样式 "& .MuiDataGrid-row": { cursor: "pointer" } }} > <DataGrid rows={mockDatareworks} columns={columns} components={{ Toolbar: GridToolbar }} // 新增:绑定行点击事件 onRowClick={handleRowClick} /> </Box> </Box> ); }; export default Reworks;
3. 创建详情页组件(ReworkDetail.jsx)
创建详情页组件,通过useParams获取URL中的id参数,然后从mock数据中匹配对应记录并展示:
import { Box, Typography, Paper } from "@mui/material"; import { useParams, useNavigate } from 'react-router-dom'; import { mockDatareworks } from "../data/mockData"; import { tokens } from "../theme"; import { useTheme } from "@mui/material"; const ReworkDetail = () => { const theme = useTheme(); const colors = tokens(theme.palette.mode); const { id } = useParams(); // 获取URL中的id参数 const navigate = useNavigate(); // 根据id查找对应的返工记录 const rework = mockDatareworks.find(item => item.id === parseInt(id)); // 如果找不到对应记录的 fallback if (!rework) { return ( <Box m="20px"> <Typography variant="h6" color={colors.grey[100]}>找不到对应的返工记录</Typography> <button onClick={() => navigate('/reworks')} style={{ marginTop: '16px', padding: '8px 16px', backgroundColor: colors.blueAccent[700], color: 'white', border: 'none', borderRadius: '4px', cursor: 'pointer' }} >返回列表</button> </Box> ); } return ( <Box m="20px"> <Paper sx={{ p: 3, backgroundColor: colors.primary[400] }}> <Typography variant="h4" gutterBottom color={colors.grey[100]}> 返工详情 #{rework.id} </Typography> <Box sx={{ mt: 2, gap: 1, display: 'flex', flexDirection: 'column' }}> <Typography variant="subtitle1" color={colors.grey[200]}> 日期: {rework.return_date} </Typography> <Typography variant="subtitle1" color={colors.grey[200]}> 客户: {rework.customer_name} </Typography> <Typography variant="subtitle1" color={colors.grey[200]}> 产品: {rework.product_name} </Typography> <Typography variant="subtitle1" color={colors.grey[200]}> 数量: {rework.rework_quantity} </Typography> </Box> <Box sx={{ mt: 3 }}> <button onClick={() => navigate('/reworks')} style={{ padding: '8px 16px', backgroundColor: colors.blueAccent[700], color: 'white', border: 'none', borderRadius: '4px', cursor: 'pointer' }} > 返回列表 </button> </Box> </Paper> </Box> ); }; export default ReworkDetail;
注意事项
- 如果你的
mockDatareworks中id是字符串类型,删除parseInt直接对比即可 - 可根据需求自定义详情页的样式和展示字段
- 若使用类组件,需用
withRouter高阶组件替代useNavigate和useParams
内容的提问来源于stack exchange,提问作者Sunny Liao
相关产品推荐
相关产品推荐

