如何在Material UI Table中编辑表格行?
解决Material UI编辑模态框更新表格数据的问题
我用Material UI做CRUD表格,这是第一个React项目,目前能把数据传入编辑模态框,但不知道怎么实现表格数据更新。以下是我的ResponsiveDialog组件代码:
export default function ResponsiveDialog({dataParent1,dataParent2}) { const [open, setOpen] = React.useState(false); const theme = useTheme(); const fullScreen = useMediaQuery(theme.breakpoints.down('md')); const handleClickOpen = () => { setOpen(true); }; const handleClose = () => { setOpen(false); }; return ( <div> <Button variant="outlined" color='success' onClick={handleClickOpen}> Edit </Button> <Dialog fullScreen={fullScreen} open={open} onClose={handleClose} aria-labelledby="responsive-dialog-title" > <DialogTitle id="responsive-dialog-title">{"Edit Post"} </DialogTitle> <DialogContent> <Divider variant="middle"/> <DialogContentText> Title </DialogContentText> <TextField id="outlined-basic" defaultValue={dataParent1} style = {{width: 500}} variant="outlined" /> <DialogContentText> Description </DialogContentText> <TextField id="outlined-basic" multiline rows={4} defaultValue={dataParent2} style = {{width: 500}} variant="outlined" /> </DialogContent> <DialogActions> <Button autoFocus variant="outlined" color='error' onClick={handleClose}> Exit </Button> <Button color='success' variant="outlined" onClick={handleClose} autoFocus> Save Changes </Button> </DialogActions> </Dialog> </div> ); }
解决步骤:
1. 给Dialog添加受控状态管理输入值
现在的TextField用defaultValue是静态赋值,需要改成受控组件,用useState管理输入内容,打开模态框时初始化数据:
export default function ResponsiveDialog({ dataParent1, dataParent2, onUpdate, itemId }) { const [open, setOpen] = React.useState(false); const [title, setTitle] = React.useState(''); const [description, setDescription] = React.useState(''); const theme = useTheme(); const fullScreen = useMediaQuery(theme.breakpoints.down('md')); const handleClickOpen = () => { // 打开模态框时初始化输入值 setTitle(dataParent1); setDescription(dataParent2); setOpen(true); }; const handleClose = () => { setOpen(false); }; // 保存修改的函数 const handleSave = () => { // 把更新后的数据传给父组件 onUpdate(itemId, { title, description }); handleClose(); }; return ( <div> <Button variant="outlined" color='success' onClick={handleClickOpen}> Edit </Button> <Dialog fullScreen={fullScreen} open={open} onClose={handleClose} aria-labelledby="responsive-dialog-title" > <DialogTitle id="responsive-dialog-title">{"Edit Post"}</DialogTitle> <DialogContent> <Divider variant="middle"/> <DialogContentText>Title</DialogContentText> <TextField id="outlined-title" value={title} onChange={(e) => setTitle(e.target.value)} style={{width: 500}} variant="outlined" /> <DialogContentText>Description</DialogContentText> <TextField id="outlined-description" multiline rows={4} value={description} onChange={(e) => setDescription(e.target.value)} style={{width: 500}} variant="outlined" /> </DialogContent> <DialogActions> <Button autoFocus variant="outlined" color='error' onClick={handleClose}> Exit </Button> <Button color='success' variant="outlined" onClick={handleSave} autoFocus> Save Changes </Button> </DialogActions> </Dialog> </div> ); }
2. 父组件传递更新回调并处理数据源更新
假设父组件里有表格的数据源(比如posts数组),需要传递onUpdate函数给Dialog,同时传递每条数据的ID用来定位更新项:
// 父组件示例(比如App.js) export default function App() { const [posts, setPosts] = React.useState([ { id: 1, title: "First Post", description: "First description" }, { id: 2, title: "Second Post", description: "Second description" } ]); // 处理更新的函数 const handleUpdatePost = (postId, updatedData) => { setPosts(posts.map(post => post.id === postId ? {...post, ...updatedData} : post )); }; return ( <div> {/* 表格部分 */} <Table> {/* 表格行渲染 */} {posts.map(post => ( <TableRow key={post.id}> <TableCell>{post.title}</TableCell> <TableCell>{post.description}</TableCell> <TableCell> <ResponsiveDialog dataParent1={post.title} dataParent2={post.description} itemId={post.id} onUpdate={handleUpdatePost} /> </TableCell> </TableRow> ))} </Table> </div> ); }
关键说明:
- 把TextField改成受控组件,用
value绑定状态,onChange更新状态,这样能实时获取用户输入的修改内容。 - 父组件通过
onUpdate回调接收Dialog传回的更新数据,利用数组的map方法找到对应ID的项,替换成更新后的数据,从而更新表格的数据源。 - 传递
itemId是为了在父组件中精准定位要更新的表格行数据。
内容的提问来源于stack exchange,提问作者Artani
相关产品推荐
相关产品推荐

