React Material UI Core表格实现行点击获取数据并跳转至新路由的方案
Alright, let's get this sorted. You've got a Material UI table with pagination, sorting, and filtering, and now you want each row to be clickable—when clicked, it should grab the row's data and navigate to a new route. Here's exactly how to implement this with your existing code:
Step 1: Set Up React Router (if not already done)
First, make sure you have react-router-dom installed and configured in your app. If you haven't already:
npm install react-router-dom # or yarn add react-router-dom
Wrap your root component (usually in App.js) with BrowserRouter:
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; import ViewAllUsers from './ViewAllUsers'; import UserDetails from './UserDetails'; // Your target component function App() { return ( <Router> <Routes> <Route path="/" element={<ViewAllUsers />} /> <Route path="/user-details" element={<UserDetails />} /> </Routes> </Router> ); }
Step 2: Modify the ViewAllUsers Component
We'll add a click handler to each table row, use React Router's useNavigate hook to jump to the new route, and pass the row data via route state.
Here's the updated code with changes highlighted:
import { useNavigate } from 'react-router-dom'; // Add this import import { Paper, Toolbar, TableBody, TableRow, TableCell } from '@mui/material'; import Controls from './Controls'; // Assuming this is your custom input component import useTable from './useTable'; import classes from './styles'; // Your existing styles export default function ViewAllUsers() { const [filterFn, setFilterFn] = useState({ fn: items => { return items; } }) const records = ....//List of records const { TblContainer, TblHead, TblPagination, recordsAfterPagingAndSorting } = useTable(records, headCells, filterFn); // Initialize the navigate hook const navigate = useNavigate(); const handleSearch = e => { let target = e.target; //Handle search (your existing code) } // Add this click handler function const handleRowClick = (rowData) => { // Navigate to the new route and pass the row data in state // This keeps data out of the URL (good for sensitive info) navigate('/user-details', { state: { user: rowData } }); } return ( <> <Paper className={classes.pageContent}> <Toolbar> <Controls.Input onChange={handleSearch}/> </Toolbar> <TblContainer> <TblHead /> <TableBody> { recordsAfterPagingAndSorting().map(item => ( <TableRow key={item.id} onClick={() => handleRowClick(item)} // Add click handler sx={{ cursor: 'pointer' }} // Add pointer cursor for UX > <TableCell>{item.id}</TableCell> <TableCell>{item.fullName}</TableCell> </TableRow> )) } </TableBody> </TblContainer> <TblPagination/> </Paper> </> ) }
Step 3: Receive Data in the Target Component
Create (or update) your target component (e.g., UserDetails.js) to retrieve the passed data using React Router's useLocation hook:
import { useLocation } from 'react-router-dom'; export default function UserDetails() { const location = useLocation(); // Extract the user data from route state (add optional chaining to avoid errors) const user = location.state?.user; // Handle case where no data is passed if (!user) { return <div>No user data available</div>; } return ( <div style={{ padding: '2rem' }}> <h1>User Profile</h1> <p><strong>ID:</strong> {user.id}</p> <p><strong>Full Name:</strong> {user.fullName}</p> {/* Add more fields from your row data as needed */} </div> ); }
Key Notes:
- Route State vs URL Params: We used route state to pass data because it keeps sensitive info out of the URL. If you prefer to pass the
idin the URL (e.g.,/user-details/123), you can modify the navigate call tonavigate(/user-details/${item.id})and useuseParams()in the target component to fetch the id, then retrieve the full data from your source. - UX Improvement: The
sx={{ cursor: 'pointer' }}on theTableRowgives users visual feedback that the row is clickable. - Error Handling: We added a check for
userin the target component to handle cases where someone navigates directly to/user-detailswithout clicking a row.
内容的提问来源于stack exchange,提问作者nour

