Материал интерфейса пользователя Таблица не отображается правильно при смене страницы
Получая массив объектов Artist через реквизиты, я хочу иметь таблицу контрольного списка. Кажется, все работает, однако при изменении страницы / сортировки отображается больше, чем строки "rowPerPage". Также этот эффект дублируется при переключении назад и вперед.
Объект Artist: {id: номер, имя: строка, электронная почта: строка, флажок: логическое значение}
пример props.values.artists : [{id: 1, имя: «Тестер», электронная почта: «mail», проверено: false}, {id: 1, имя: «bob», электронная почта: «test@live.com», проверено: false}]
извините, что код не очень работоспособен!
вот пример, который я использовал из материала: https://material-ui.com/components/tables/
import React, { useEffect } from "react";
import clsx from "clsx";
import {
createStyles,
lighten,
makeStyles,
Theme
} from "@material-ui/core/styles";
import Table from "@material-ui/core/Table";
import TableBody from "@material-ui/core/TableBody";
import TableCell from "@material-ui/core/TableCell";
import TableContainer from "@material-ui/core/TableContainer";
import TableHead from "@material-ui/core/TableHead";
import TablePagination from "@material-ui/core/TablePagination";
import TableRow from "@material-ui/core/TableRow";
import TableSortLabel from "@material-ui/core/TableSortLabel";
import Toolbar from "@material-ui/core/Toolbar";
import Typography from "@material-ui/core/Typography";
import Paper from "@material-ui/core/Paper";
import Checkbox from "@material-ui/core/Checkbox";
/*function createData(id: number, name: string, email: string, checked: boolean) {
return { id, name, email, checked };
}*/
function desc(a: any, b: any, orderBy: any) {
if (b[orderBy] < a[orderBy]) {
return -1;
}
if (b[orderBy] > a[orderBy]) {
return 1;
}
return 0;
}
function stableSort<T>(array: Object[], cmp: (a: T, b: T) => number) {
const stabilizedThis = array.map((el, index) => [el, index] as [T, number]);
stabilizedThis.sort((a, b) => {
const order = cmp(a[0], b[0]);
if (order !== 0) return order;
return a[1] - b[1];
});
return stabilizedThis.map(el => el[0]);
}
type Order = "asc" | "desc";
function getSorting<K extends keyof any>(
order: Order,
orderBy: K
): (a: { [key in K]: any }, b: { [key in K]: any }) => number {
return order === "desc"
? (a, b) => desc(a, b, orderBy)
: (a, b) => -desc(a, b, orderBy);
}
interface HeadCell {
disablePadding: boolean;
id: any;
label: string;
numeric: boolean;
}
const headCells: HeadCell[] = [
{
id: "name",
numeric: false,
disablePadding: true,
label: "Artists"
},
{
id: "email",
numeric: true,
disablePadding: false,
label: "Email"
}
];
interface EnhancedTableProps {
classes: ReturnType<typeof useStyles>;
numSelected: number;
onRequestSort: (event: React.MouseEvent<unknown>, property: any) => void;
onSelectAllClick: (
event: React.ChangeEvent<HTMLInputElement>,
checked: boolean
) => void;
order: Order;
orderBy: string;
rowCount: number;
}
function EnhancedTableHead(props: EnhancedTableProps) {
const {
classes,
onSelectAllClick,
order,
orderBy,
numSelected,
rowCount,
onRequestSort
} = props;
const createSortHandler = (property: any) => (
event: React.MouseEvent<unknown>
) => {
onRequestSort(event, property);
};
return (
<TableHead>
<TableRow>
<TableCell padding="checkbox">
<Checkbox
indeterminate={numSelected > 0 && numSelected < rowCount}
checked={numSelected === rowCount}
onChange={onSelectAllClick}
inputProps={{ "aria-label": "select all desserts" }}
/>
</TableCell>
{headCells.map(headCell => (
<TableCell
key={headCell.id}
align={headCell.numeric ? "right" : "left"}
padding={headCell.disablePadding ? "none" : "default"}
sortDirection={orderBy === headCell.id ? order : false}
>
<TableSortLabel
active={orderBy === headCell.id}
direction={orderBy === headCell.id ? order : "asc"}
onClick={createSortHandler(headCell.id)}
>
{headCell.label}
{orderBy === headCell.id ? (
<span className={classes.visuallyHidden}>
{order === "desc" ? "sorted descending" : "sorted ascending"}
</span>
) : null}
</TableSortLabel>
</TableCell>
))}
</TableRow>
</TableHead>
);
}
const useToolbarStyles = makeStyles((theme: Theme) =>
createStyles({
root: {
paddingLeft: theme.spacing(2),
paddingRight: theme.spacing(1)
},
highlight:
theme.palette.type === "light"
? {
color: theme.palette.secondary.main,
backgroundColor: lighten(theme.palette.secondary.light, 0.85)
}
: {
color: theme.palette.text.primary,
backgroundColor: theme.palette.secondary.dark
},
title: {
flex: "1 1 100%"
}
})
);
interface EnhancedTableToolbarProps {
numSelected: number;
}
const EnhancedTableToolbar = (props: EnhancedTableToolbarProps) => {
const classes = useToolbarStyles();
const { numSelected } = props;
return (
<Toolbar
className={clsx(classes.root, {
[classes.highlight]: numSelected > 0
})}
>
{numSelected > 0 ? (
<Typography
className={classes.title}
color="inherit"
variant="subtitle1"
>
{numSelected} artists selected
</Typography>
) : (
<Typography className={classes.title} variant="h6" id="tableTitle">
Choose artists
</Typography>
)}
</Toolbar>
);
};
const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: {
width: "100%"
},
paper: {
width: "100%",
marginBottom: theme.spacing(2)
},
table: {
minWidth: 750
},
visuallyHidden: {
border: 0,
clip: "rect(0 0 0 0)",
height: 1,
margin: -1,
overflow: "hidden",
padding: 0,
position: "absolute",
top: 20,
width: 1
}
})
);
export default (props: any) => {
const classes = useStyles();
const [order, setOrder] = React.useState<Order>("asc");
const [orderBy, setOrderBy] = React.useState<any>("name");
//const [selected, setSelected] = React.useState<string[]>([]);
const [page, setPage] = React.useState(0);
const [rowsPerPage, setRowsPerPage] = React.useState(5);
const handleRequestSort = (
event: React.MouseEvent<unknown>,
property: any
) => {
const isAsc = orderBy === property && order === "asc";
setOrder(isAsc ? "desc" : "asc");
setOrderBy(property);
};
const handleSelectAllClick = (event: React.ChangeEvent<HTMLInputElement>) => {
if (event.target.checked) {
console.log("merker alle");
props.values.artists.map((artist: any) => {
artist.checked = true;
});
props.handleChange(props.values.artists, "artists");
} else {
console.log("umerker alle");
props.values.artists.map((artist: any) => {
artist.checked = false;
});
props.handleChange(props.values.artists, "artists");
}
};
const handleClick = (event: React.MouseEvent<unknown>, id: number) => {
var prevStatus: boolean = props.values.artists.find(
(artist: any) => artist.id === id
).checked;
props.values.artists.find(
(artist: any) => artist.id === id
).checked = !prevStatus;
props.handleChange(props.values.artists, "artists");
};
const handleChangePage = (event: unknown, newPage: number) => {
setPage(newPage);
console.log("tomme sider" + emptyRows);
console.log("rader per side" + rowsPerPage);
console.log("sidenr " + page);
console.log("artist " + props.values.artists);
};
const handleChangeRowsPerPage = (
event: React.ChangeEvent<HTMLInputElement>
) => {
setRowsPerPage(parseInt(event.target.value, 10));
setPage(0);
};
const emptyRows =
rowsPerPage -
Math.min(rowsPerPage, props.values.artists.length - page * rowsPerPage);
let amtSelected = props.values.artists.filter(function(artist: any) {
return artist.checked === true;
}).length;
useEffect(() => {
console.log("useEff");
props.handleChange(props.values.artists, "artists");
}, [page]);
return (
<div className={classes.root}>
<Paper className={classes.paper}>
<EnhancedTableToolbar numSelected={amtSelected} />
<TableContainer>
<Table
className={classes.table}
aria-labelledby="tableTitle"
aria-label="enhanced table"
>
<EnhancedTableHead
classes={classes}
numSelected={amtSelected}
order={order}
orderBy={orderBy}
onSelectAllClick={handleSelectAllClick}
onRequestSort={handleRequestSort}
rowCount={props.values.artists.length}
/>
<TableBody>
{stableSort(props.values.artists, getSorting(order, orderBy))
.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
.map((row: any, index: number) => {
const isItemSelected = row.checked;
const labelId = `enhanced-table-checkbox-${index}`;
return (
<TableRow
hover
onClick={event => handleClick(event, row.id)}
role="checkbox"
aria-checked={isItemSelected}
tabIndex={-1}
key={row.name}
selected={isItemSelected}
>
<TableCell padding="checkbox">
<Checkbox
checked={isItemSelected}
inputProps={{ "aria-labelledby": labelId }}
/>
</TableCell>
<TableCell
component="th"
id={labelId}
scope="row"
padding="none"
>
{row.name}
</TableCell>
<TableCell align="right">{row.email}</TableCell>
</TableRow>
);
})}
{emptyRows > 0 && (
<TableRow style={{ height: 53 * emptyRows }}>
<TableCell colSpan={6} />
</TableRow>
)}
</TableBody>
</Table>
</TableContainer>
<TablePagination
rowsPerPageOptions={[5, 10, 25]}
component="div"
count={props.values.artists.length}
rowsPerPage={rowsPerPage}
page={page}
onChangePage={handleChangePage}
onChangeRowsPerPage={handleChangeRowsPerPage}
/>
</Paper>
</div>
);
};