如何为多个 Collapse(功能组件)创建动态状态

How to make dynamic state for multiple Collapse (functional component)

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

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>
  )   
}