I have one collapse menu that is hard-coded. I'm controlling whether it's open or closed using a single state surveysOpen
:
<ListItemButton onClick={handleClick}>
<ListItemIcon>
<FolderIcon sx={{ color: theme => theme.palette.primary.main }} />
</ListItemIcon>
<ListItemText primary='All surveys' />
{surveysOpen ? <ExpandLess /> : <ExpandMore />}
</ListItemButton>
<Collapse in={surveysOpen} timeout='auto' unmountOnExit>
{isSurveysLoading || isSurveysRefetching ? (
<LoadingProgress inSidebar />
) : isAdmin ? (
adminContent
) : (
clientContent
)}
</Collapse>
Now the problem is, I will have data coming from an API. I want to render the above code for each item.
I obviously can't create a useState
for each one because I don't know how many there is (if any)
const [surveysOpen, setSurveysOpen] = useState(false);
How do I control whether each one is opened or closed?
{surveysOpen ? <ExpandLess /> : <ExpandMore />}
Is there a dynamic way to update the state of unknown # of items?
CodePudding user response:
There's a few ways to approach this. The first, and the one I consider the best is to make each Survey its own component, and let it track the open/close state for itself.
The second solution, which will may be easier to implement is to keep it the way you're doing it, and just track it using key-value pairs:
const [openMap, setOpenMap] = useState(new Map());
onSurveysLoaded = (surveys) => {
...
openMap.set(..., ...);
setOpenMap(new Map(openMap));
};
...
surveyIsOpen = openMap.get(...)