如何为多个Collapse(功能组件)制作动态状态



我想为状态中的每个数据折叠,只需单击每个数据即可打开它。这些是我的代码:

import ListSubheader from '@mui/material/ListSubheader';
import List from '@mui/material/List';
import ListItemButton from '@mui/material/ListItemButton';
import ListItemText from '@mui/material/ListItemText';
import Collapse from '@mui/material/Collapse';
import ExpandLess from '@mui/icons-material/ExpandLess';
import ExpandMore from '@mui/icons-material/ExpandMore';
const MyClass = ({data}) => {
const [open, setOpen] = React.useState(false)
const handleClick = () =>{
setOpen(!open)
};
return (
<List
sx={{ width: '100%', maxWidth: 360, bgcolor: 'background.paper' }}
component="nav"
aria-labelledby='{item.listCities.id}'
subheader={
<ListSubheader component="div" id='{item.listCities.id}'>
Lists
</ListSubheader>
}>
{
data.map(item =>
<Box component="section" key={item.listCities.id}>
<ListItemButton onClick={handleClick}>
<ListItemText primary={item.listCities.city} />
{open ? <ExpandLess /> : <ExpandMore />}
</ListItemButton>
<Collapse in={open} timeout="auto" unmountOnExit>
<List component="div" disablePadding>
<ListItemButton sx={{ pl: 4 }}>
<ListItemText primary={item.listCities.names} />
</ListItemButton>
</List>
</Collapse>
</Box>
)
}
</List>
)   
}

这是我的组件,它被调用的数据是:

const ListItems= [
{
listCities:{city: "one", id:"1", names: ["name 1", "name 2", "name 3"]}
},
{
listCities:{city: "two", id:"2", names: ["name 1", "name 2", "name 3"]}
}
]

<MyClass data={ListItems}></MyClass>

我使用了这个API:
https://mui.com/components/lists/#nested-list


如果有人知道,请帮助我。

我建议在状态中使用一个数组来存储您的对象,另外还有一个名为isOpen的新元素,以测试每个对象是否打开。为此,您可以使用钩子useEffect(),在每次到达的数据更改时运行一个函数来处理它并为每个对象添加新元素,如下所示:

import ListSubheader from '@mui/material/ListSubheader';
import List from '@mui/material/List';
import ListItemButton from '@mui/material/ListItemButton';
import ListItemText from '@mui/material/ListItemText';
import Collapse from '@mui/material/Collapse';
import ExpandLess from '@mui/icons-material/ExpandLess';
import ExpandMore from '@mui/icons-material/ExpandMore';
const MyClass = ({data}) => {
const [objectsList, setObjectsList] = React.useState([])
const handleClick = (item) =>{
setObjectsList(
objectsList.map(e => e.listCities.id === item.listCities.id ? ({...e, isOpen: !e.isOpen} ) : (e))
)
};
React.useEffect(() => {
setObjectsList(
data.map(e => ({...e, isOpen: false}))
);
}, [data])
return (
<List
sx={{ width: '100%', maxWidth: 360, bgcolor: 'background.paper' }}
component="nav"
aria-labelledby='{item.listCities.id}'
subheader={
<ListSubheader component="div" id='{item.listCities.id}'>
Lists
</ListSubheader>
}>
{
objectsList.map(item =>
<Box component="section" key={item.listCities.id}>
<ListItemButton onClick={() => handleClick(item)}>
<ListItemText primary={item.listCities.city} />
{item.isOpen ? <ExpandLess /> : <ExpandMore />}
</ListItemButton>
<Collapse in={item.isOpen} timeout="auto" unmountOnExit>
<List component="div" disablePadding>
<ListItemButton sx={{ pl: 4 }}>
<ListItemText primary={item.listCities.names} />
</ListItemButton>
</List>
</Collapse>
</Box>
)
}
</List>
)   
}

根据Haroun Darjaj的答案,我们可以通过数组的user index来更简单地管理它:

const [isOpenCollapse, setIsOpenCollapse] = useState(null);
const handleOpen = (clickedIndex) => {
if (isOpenCollapse === clickedIndex) {
setIsOpenCollapse(null);
} else {
setIsOpenCollapse(clickedIndex);
}
};
[...]
return (
<List>
{arr.map((elm, index) => {
return (
<>
<ListItem key={elm.ID} onClick={() => handleOpen(index)} id="listItem">
{isOpenCollapse === index ? <ExpandLess /> : <ExpandMore />}
<Box>
<Typography>{elm.label}</Typography>
</Box>
</ListItem>
<Collapse in={isOpenCollapse === index} timeout="auto" unmountOnExit>
<p>PUT SOMETHING HERE</p>
</Collapse>
</>
);
})}
</List>;
)

最新更新