My nested list in ReactJS opens all sublists when I expand one category
import * as React from 'react';
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';
export default function SideBar() {
const [open, setOpen] = React.useState(false);
const handleClick = () => {
setOpen(!open);
};
return (
<List
sx={{ width: '100%', maxWidth: 360, bgcolor: 'background.paper' }}
component="nav"
aria-labelledby="nested-list-subheader"
subheader={
<ListSubheader component="div" id="nested-list-subheader">
courses
</ListSubheader>
}
>
<ListItemButton onClick={() => handleClick()}>
<ListItemText primary="Course 1" />
{open ? <ExpandLess /> : <ExpandMore />}
</ListItemButton>
<Collapse in={open} timeout="auto" unmountOnExit>
<List component="div" disablePadding>
<ListItemButton sx={{ pl: 4 }}>
<ListItemText primary="Research Paper" />
</ListItemButton>
</List>
</Collapse>
<ListItemButton>
<ListItemText primary="Course 2" />
{open ? <ExpandLess /> : <ExpandMore />}
</ListItemButton>
<ListItemButton onClick={() => handleClick()}>
<ListItemText primary="Course 3" />
{open ? <ExpandLess /> : <ExpandMore />}
</ListItemButton>
<Collapse in={open} timeout="auto" unmountOnExit>
<List component="div" disablePadding>
<ListItemButton sx={{ pl: 4 }}>
<ListItemText primary="Exams" />
</ListItemButton>
</List>
</Collapse>
</List>
);
}
I found the problem might be that I am using an binary operator to open all the lists. I found this solution ReactJs nested list collapse for only one list item but was unable to implement it properly. Any ideas on what I could do?
The issue is all the list components share a single state. Make ListItemButton
and Collapse
a single component called MyCollapseComponent
which holds toggle logic:
const MyCollapsibleComponent = ({ course, content }) => {
const [open, setOpen] = React.useState(false);
const handleClick = () => {
setOpen(!open);
};
return (
<>
<ListItemButton onClick={() => handleClick()}>
<ListItemText primary={course} />
{open ? <ExpandLess /> : <ExpandMore />}
</ListItemButton>
<Collapse in={open} timeout="auto" unmountOnExit>
<List component="div" disablePadding>
<ListItemButton sx={{ pl: 4 }}>
<ListItemText primary={content} />
</ListItemButton>
</List>
</Collapse>
</>
);
};
Then create individual MyCollapsibleComponent
providing the props you want:
export default function SideBar() {
return (
<List
sx={{ width: "100%", maxWidth: 360, bgcolor: "background.paper" }}
component="nav"
aria-labelledby="nested-list-subheader"
subheader={
<ListSubheader component="div" id="nested-list-subheader">
courses
</ListSubheader>
}
>
<MyCollapsibleComponent course="Course 1" content="Research Paper" />
<MyCollapsibleComponent course="Course 2" content="" />
<MyCollapsibleComponent course="Course 3" content="Exams" />
</List>
);
}
Code Sandbox Demo