在可折叠 table reactjs 中使用地图
using map in collapsible table reactjs
我有一个可折叠的 table,看起来像 this。但是,当我单击一行时,两行都会展开。
这是我的代码的样子:
const Transaction = ({ categories }) => {
const [open, setOpen] = useState(false);
let categoryList = categories.map((category, index) => {
return (
<TableRow key={index}>
<TableCell>
<IconButton size="small" onClick={() => setOpen(!open)}>
{open ? <KeyboardArrowUpIcon /> : <KeyboardArrowDownIcon />}
</IconButton>
</TableCell>
<TableCell component="th" scope="row">
{category}
</TableCell>
<TableCell />
<TableCell />
<TableCell />
<TableCell />
</TableRow>
);
});
return (
<div className={classes.root}>
<Grid container spacing={2}>
<Grid item xs={12}>
<TableContainer component={Paper}>
<Table>
<TableHead>
<TableRow>
<TableCell />
<TableCell>Category</TableCell>
<TableCell />
<TableCell />
<TableCell />
<TableCell />
</TableRow>
</TableHead>
<TableBody>
{categoryList}
</TableBody>
</Table>
</TableContainer>
</Grid>
</Grid>
</div>
);
};
在我的 categoryList 中,我使用索引作为键,但它仍然扩展了两行而不是选定的特定行。我怎样才能只展开一行?
您的 table 行需要控制它们自己的 open
状态。目前,您构建代码的方式它们都共享相同的状态并且单击 table 行中的任何一个将引用相同的处理程序来更改 open
状态,所以这就是为什么您的 table 行同时打开和关闭。
因此,此解决方案不是让 open
保存单个布尔值,而是保存一个布尔值数组,这些布尔值最初都设置为 false。
const [open, setOpen] = useState(categories.map(() => false));
这将创建一个大小为 categories
的布尔数组。
此外,OnClick
函数自然要稍作改动:
onClick={() => {
setOpen((pOpen) => pOpen.map((o, i) => {
if (i === index) return !o;
return o;
}));
}}
现在您可以使用索引 open[index]
了解打开的内容。
{open[index] ? <KeyboardArrowUpIcon /> : <KeyboardArrowDownIcon />}
完整代码段如下:
const Transaction = ({ categories }) => {
/*
* Change this [Origninal]:
* const [open, setOpen] = useState(false);
* To this:
*/
const [open, setOpen] = useState(categories.map(() => false));
React.useEffect(() => {
if (categories.length !== open.length) {
setOpen(categories.map(() => false));
}
}, [categories, open]);
let categoryList = categories.map((category, index) => {
return (
<TableRow key={index}>
<TableCell>
<IconButton size="small"
onClick={() => {
setOpen((pOpen) => pOpen.map((o, i) => {
if (i === index) return !o;
return o;
}));
}}
{open[index] ? <KeyboardArrowUpIcon /> : <KeyboardArrowDownIcon />}
</IconButton>
</TableCell>
<TableCell component="th" scope="row">
{category}
</TableCell>
<TableCell />
<TableCell />
<TableCell />
<TableCell />
</TableRow>
);
});
return (
<div className={classes.root}>
<Grid container spacing={2}>
<Grid item xs={12}>
<TableContainer component={Paper}>
<Table>
<TableHead>
<TableRow>
<TableCell />
<TableCell>Category</TableCell>
<TableCell />
<TableCell />
<TableCell />
<TableCell />
</TableRow>
</TableHead>
<TableBody>
{categoryList}
</TableBody>
</Table>
</TableContainer>
</Grid>
</Grid>
</div>
);
};
我有一个可折叠的 table,看起来像 this。但是,当我单击一行时,两行都会展开。
这是我的代码的样子:
const Transaction = ({ categories }) => {
const [open, setOpen] = useState(false);
let categoryList = categories.map((category, index) => {
return (
<TableRow key={index}>
<TableCell>
<IconButton size="small" onClick={() => setOpen(!open)}>
{open ? <KeyboardArrowUpIcon /> : <KeyboardArrowDownIcon />}
</IconButton>
</TableCell>
<TableCell component="th" scope="row">
{category}
</TableCell>
<TableCell />
<TableCell />
<TableCell />
<TableCell />
</TableRow>
);
});
return (
<div className={classes.root}>
<Grid container spacing={2}>
<Grid item xs={12}>
<TableContainer component={Paper}>
<Table>
<TableHead>
<TableRow>
<TableCell />
<TableCell>Category</TableCell>
<TableCell />
<TableCell />
<TableCell />
<TableCell />
</TableRow>
</TableHead>
<TableBody>
{categoryList}
</TableBody>
</Table>
</TableContainer>
</Grid>
</Grid>
</div>
);
};
在我的 categoryList 中,我使用索引作为键,但它仍然扩展了两行而不是选定的特定行。我怎样才能只展开一行?
您的 table 行需要控制它们自己的 open
状态。目前,您构建代码的方式它们都共享相同的状态并且单击 table 行中的任何一个将引用相同的处理程序来更改 open
状态,所以这就是为什么您的 table 行同时打开和关闭。
因此,此解决方案不是让 open
保存单个布尔值,而是保存一个布尔值数组,这些布尔值最初都设置为 false。
const [open, setOpen] = useState(categories.map(() => false));
这将创建一个大小为 categories
的布尔数组。
此外,OnClick
函数自然要稍作改动:
onClick={() => {
setOpen((pOpen) => pOpen.map((o, i) => {
if (i === index) return !o;
return o;
}));
}}
现在您可以使用索引 open[index]
了解打开的内容。
{open[index] ? <KeyboardArrowUpIcon /> : <KeyboardArrowDownIcon />}
完整代码段如下:
const Transaction = ({ categories }) => {
/*
* Change this [Origninal]:
* const [open, setOpen] = useState(false);
* To this:
*/
const [open, setOpen] = useState(categories.map(() => false));
React.useEffect(() => {
if (categories.length !== open.length) {
setOpen(categories.map(() => false));
}
}, [categories, open]);
let categoryList = categories.map((category, index) => {
return (
<TableRow key={index}>
<TableCell>
<IconButton size="small"
onClick={() => {
setOpen((pOpen) => pOpen.map((o, i) => {
if (i === index) return !o;
return o;
}));
}}
{open[index] ? <KeyboardArrowUpIcon /> : <KeyboardArrowDownIcon />}
</IconButton>
</TableCell>
<TableCell component="th" scope="row">
{category}
</TableCell>
<TableCell />
<TableCell />
<TableCell />
<TableCell />
</TableRow>
);
});
return (
<div className={classes.root}>
<Grid container spacing={2}>
<Grid item xs={12}>
<TableContainer component={Paper}>
<Table>
<TableHead>
<TableRow>
<TableCell />
<TableCell>Category</TableCell>
<TableCell />
<TableCell />
<TableCell />
<TableCell />
</TableRow>
</TableHead>
<TableBody>
{categoryList}
</TableBody>
</Table>
</TableContainer>
</Grid>
</Grid>
</div>
);
};