'TransferList is so slow
I made faster TextField and Select referring to below.
TextField Unnecessary Re-renders
But even though I used useMemo TransferList could make faster just a little.
My current code is here:
import Grid from "@mui/material/Grid";
import List from "@mui/material/List";
import ListItem from "@mui/material/ListItem";
import ListItemIcon from "@mui/material/ListItemIcon";
import ListItemText from "@mui/material/ListItemText";
import Checkbox from "@mui/material/Checkbox";
import Button from "@mui/material/Button";
import Paper from "@mui/material/Paper";
import React, { useMemo } from "react";
interface TransferListProps {
items: any;
setData: (value: any) => void;
}
interface Props {
customList: any;
right: any[];
left: any[];
handleAllRight: any;
handleCheckedRight: any;
leftChecked: any;
handleCheckedLeft: any;
rightChecked: any;
handleAllLeft: any;
}
function not(a: readonly number[], b: readonly number[]) {
console.log(a.filter((value) => b.indexOf(value) === -1));
return a.filter((value) => b.indexOf(value) === -1);
}
function intersection(a: readonly number[], b: readonly number[]) {
return a.filter((value) => b.indexOf(value) !== -1);
}
const TransferListComponent = React.memo((props: Props) => {
return (
<Grid container spacing={2} justifyContent="start" alignItems="center">
<Grid item>{props.customList(props.left)}</Grid>
<Grid item>
<Grid container direction="column" alignItems="center">
<Button
sx={{ my: 0.5 }}
variant="outlined"
size="small"
onClick={props.handleAllRight}
disabled={props.left.length === 0}
aria-label="move all right"
>
≫
</Button>
<Button
sx={{ my: 0.5 }}
variant="outlined"
size="small"
onClick={props.handleCheckedRight}
disabled={props.leftChecked.length === 0}
aria-label="move selected right"
>
>
</Button>
<Button
sx={{ my: 0.5 }}
variant="outlined"
size="small"
onClick={props.handleCheckedLeft}
disabled={props.rightChecked.length === 0}
aria-label="move selected left"
>
<
</Button>
<Button
sx={{ my: 0.5 }}
variant="outlined"
size="small"
onClick={props.handleAllLeft}
disabled={props.right.length === 0}
aria-label="move all left"
>
≪
</Button>
</Grid>
</Grid>
<Grid item>{props.customList(props.right)}</Grid>
</Grid>
);
});
export default function TransferList(props: TransferListProps) {
const [checked, setChecked] = React.useState<readonly any[]>([]);
const [left, setLeft] = React.useState<any[]>(
props.items.map((value: any) => {
return value.name;
})
);
const [right, setRight] = React.useState<any[]>([]);
const leftChecked = intersection(checked, left);
const rightChecked = intersection(checked, right);
const handleToggle = useMemo(
() => (value: number) => () => {
const currentIndex = checked.indexOf(value);
const newChecked = [...checked];
if (currentIndex === -1) {
newChecked.push(value);
} else {
newChecked.splice(currentIndex, 1);
}
setChecked(newChecked);
},
[rightChecked]
);
const handleAllRight = useMemo(
() => () => {
setRight(right.concat(left));
props.setData(right.concat(left));
setLeft([]);
},
[rightChecked]
);
const handleCheckedRight = useMemo(
() => () => {
setRight(right.concat(leftChecked));
props.setData(right.concat(leftChecked));
setLeft(not(left, leftChecked));
setChecked(not(checked, leftChecked));
},
[rightChecked]
);
const handleCheckedLeft = useMemo(
() => () => {
setLeft(left.concat(rightChecked));
setRight(not(right, rightChecked));
props.setData(not(right, rightChecked));
setChecked(not(checked, rightChecked));
},
[rightChecked]
);
const handleAllLeft = useMemo(
() => () => {
setLeft(left.concat(right));
setRight([]);
props.setData([]);
},
[rightChecked]
);
const customList = useMemo(
() => (items: string[]) =>
(
<Paper sx={{ width: 175, height: 230, overflow: "auto" }}>
<List dense component="div" role="list">
{items.map((value: any) => {
const labelId = `transfer-list-item-${value}-label`;
const randomNumber = Math.random();
return (
<ListItem
key={randomNumber}
role="listitem"
button
onClick={handleToggle(value)}
>
<ListItemIcon>
<Checkbox
checked={checked.indexOf(value) !== -1}
tabIndex={-1}
disableRipple
inputProps={{
"aria-labelledby": labelId,
}}
/>
</ListItemIcon>
<ListItemText id={labelId} primary={`${value}`} />
</ListItem>
);
})}
<ListItem />
</List>
</Paper>
),
[rightChecked]
);
return (
<TransferListComponent
customList={customList}
left={left}
right={right}
handleAllRight={handleAllRight}
handleCheckedRight={handleCheckedRight}
leftChecked={leftChecked}
handleCheckedLeft={handleCheckedLeft}
rightChecked={rightChecked}
handleAllLeft={handleAllLeft}
/>
);
}
This is the relation to describe parent and child.
UsersSearch → TransferList → TransferListComponent
Could you give me advise?
Thank you.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
