英文:
How to update the rows in a table in Material UI/React Table
问题
我正在使用Material UI和React工作,其中包含一个具有多个文本字段(每行一个)并允许用户删除特定行的表格。表格中的每一行都是从一个列表生成的,我正在使用React的状态钩子来跟踪列表的状态。我的目标是使用户能够删除表格中的任何行。然而,目前当用户点击删除按钮时,只有表格中的最后一行会被删除。我应该对我的代码进行哪些修改,以便用户可以删除除最后一行以外的行?
英文:
I'm working on a table in Material UI/React that has multiple text fields (per row) and allows users to delete specific rows. Each row in the table is generated from a list, and I'm using React's state hooks to keep track of the list's state. My goal is to enable users to delete any row from the table. However, at the moment, when a user clicks the delete button, only the last row in the table is deleted. What modifications should I make to my code so that users can remove rows other than the last one in the table?
Page:
import { useCallback, useMemo, useState } from 'react';
import Head from 'next/head';
import { subDays, subHours } from 'date-fns';
import ArrowDownOnSquareIcon from '@heroicons/react/24/solid/ArrowDownOnSquareIcon';
import ArrowUpOnSquareIcon from '@heroicons/react/24/solid/ArrowUpOnSquareIcon';
import PlusIcon from '@heroicons/react/24/solid/PlusIcon';
import { Box, Button, Card, Container, Stack, SvgIcon, Typography } from '@mui/material';
import { useSelection } from 'src/hooks/use-selection';
import { Layout as DashboardLayout } from 'src/layouts/dashboard/layout';
import { TestSteps } from 'src/sections/createTests/testSteps';
import { TestsSearch } from 'src/sections/viewTests/tests-search';
import { applyPagination } from 'src/utils/apply-pagination';
import Grid from '@mui/material/Grid';
import AddCircleIcon from '@mui/icons-material/AddCircle';
import { v4 as uuidv4 } from 'uuid';
const Page = () => {
const [testSteps, setTestSteps] = useState([{id: uuidv4(), text:""}, {id: uuidv4(), text:""}]);
function handleAddNewTestStep() {
const newTestSteps = testSteps.concat({id: uuidv4(), text:""});
setTestSteps(newTestSteps)
}
function handleRemove(id) {
console.log(id)
const newList = testSteps.filter((item) => item.id !== id);
console.log(newList)
setTestSteps(newList);
}
return (
<>
<Head>
<title>
Customers | Devias Kit
</title>
</Head>
<Box
component="main"
sx={{
flexGrow: 1,
py: 8
}}
>
<Container maxWidth="xl">
<Stack spacing={3}>
<Stack
direction="row"
justifyContent="space-between"
spacing={4}
>
<Stack spacing={1}>
<Typography variant="h4">
Tests Steps
</Typography>
</Stack>
</Stack>
<Card sx={{ p: 2 }}>
<Typography sx={{ mb: 2 }}>
Scenario 1 - User enters a valid name and email address and submits the form successfully.
</Typography>
<TestSteps
count={testSteps.length}
items={testSteps}
handleRemove={handleRemove}
/>
<Grid xs={12}>
<Grid xs={12}>
<Button variant="text" onClick={handleAddNewTestStep}>
<Typography>
Add New Test Step
</Typography>
<AddCircleIcon sx={{ ml: 1 }}/>
</Button>
</Grid>
</Grid>
</Card>
</Stack>
<div align="center">
<Button variant="contained" size="small" align="center" sx={{mt: 2}}
href="/viewTest"
>
Add Test Steps
</Button>
</div>
</Container>
</Box>
</>
);
};
Page.getLayout = (page) => (
<DashboardLayout>
{page}
</DashboardLayout>
);
export default Page;
MUI Table:
import PropTypes from 'prop-types';
import { format } from 'date-fns';
import {
Avatar,
Box,
Card,
Checkbox,
Stack,
Table,
TableBody,
TableCell,
TableHead,
TablePagination,
TableRow,
Typography,
} from '@mui/material';
import { Scrollbar } from 'src/components/scrollbar';
import { getInitials } from 'src/utils/get-initials';
import TextField from '@mui/material/TextField';
import Grid from '@mui/material/Grid';
import Button from '@mui/material/Button';
import AddCircleIcon from '@mui/icons-material/AddCircle';
import MenuItem from '@mui/material/MenuItem';
import CloseIcon from '@mui/icons-material/Close';
export const TestSteps = (props) => {
const {
count = 0,
handleRemove,
items = [],
onDeselectAll,
onDeselectOne,
onPageChange = () => {},
onRowsPerPageChange,
onSelectAll,
onSelectOne,
page = 0,
rowsPerPage = 0,
selected = []
} = props;
return (
<Grid xs={12}>
<Grid xs={12}>
<Scrollbar>
<Box sx={{ minWidth: 800 }}>
<Table>
<TableHead>
<TableRow>
<TableCell padding="checkbox">
Step
</TableCell>
<TableCell>
Test Step
</TableCell>
<TableCell sx={{mr: 2}}>
Page
</TableCell>
<TableCell padding="checkbox" />
</TableRow>
</TableHead>
<TableBody>
{items.map((customer, i) => {
return (
<TableRow
>
<TableCell padding="checkbox">
{i + 1}
</TableCell>
<TableCell>
<TextField
required
id="outlined-required"
label="Test Step"
placeholder="Enter Test Step"
multiline
fullWidth
/>
</TableCell>
<TableCell sx={{mr: 2}}>
<TextField
required
select
id="outlined-required"
label="Choose Page"
placeholder="Choose Page"
fullWidth
>
<MenuItem key="testpage1" value="testpage1">
testpage1.com
</MenuItem>
<MenuItem key="testpage2" value="testpage2">
testpage2.com
</MenuItem>
</TextField>
</TableCell>
<TableCell padding="checkbox">
<Button id={customer.id} onClick={event => handleRemove(event.currentTarget.id)}>
<CloseIcon />
</Button>
</TableCell>
</TableRow>
)
})}
</TableBody>
</Table>
</Box>
</Scrollbar>
</Grid>
</Grid>
);
};
答案1
得分: 1
你不需要事件对象来处理这个,你已经在通过items
来映射显示表格行,所以你可以简单地将当前迭代的项目id传递给你的handleRemove
函数:
<Button
onClick={() => {
handleRemove(customer.id);
}}
>
<CloseIcon />
</Button>
还要在返回的函数数组中的每个元素内添加一个唯一的键:
{items.map((customer, i) => {
return (
<TableRow key={i}>
//...
</TableRow>
)
})}
如果id总是不同且已定义,更好的做法是key={customer.id}
。
英文:
you don't need the event object to handle this, you are already mapping through items
to display table rows so you can simply give the item id of the current itteration to your handleRemove
function instead:
<Button
onClick={() => {
handleRemove(customer.id);
}}
>
<CloseIcon />
</Button>
also add an unique key to each element inside the returned array of function:
{items.map((customer, i) => {
return (
<TableRow key={i}>
/...
</TableRow>
)
})
better would be key={customer.id}
if ids are always deffirents and defined
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论