#reactjs #material-ui
#reactjs #материал-пользовательский интерфейс
Вопрос:
Я использую компонент Material UI nested / select ItemList для динамической генерации любого количества элементов выпадающего меню на основе того, сколько элементов принадлежит этому заголовку, как вы, возможно, можете определить из функции сопоставления. В другом файле на 1 уровень выше этого я снова сопоставляю и генерирую несколько из этих выпадающих меню, возможно ли, чтобы эти компоненты взаимодействовали друг с другом?
Это файл, о котором идет речь
const useStyles = makeStyles((theme) => ({
root: {
width: '100%',
maxWidth: 330,
backgroundColor: theme.palette.background.paper,
},
nested: {
paddingLeft: theme.spacing(4),
}
}));
export default function DropDownMenu(props) {
const classes = useStyles();
const [open, setOpen] = React.useState(true);
let unitName = props.unit[0];
let chapterList = props.unit.slice(1);
const [selectedIndex, setSelectedIndex] = React.useState(1);
const handleListItemClick = (index) => {
console.log("ItemClicked");
console.log(index);
setSelectedIndex(index);
};
const handleClick = () => {
setOpen(!open);
};
const selectMenuItem = (chapter, index) => {
props.chooseChapter(chapter)
handleListItemClick(index)
}
let dropDownUnit = chapterList.map((chapter, index) => {
return (
<ListItem button
className={classes.selected}
selected={selectedIndex === index}
onClick={() => selectMenuItem(chapter, index)}
key={index}>
<ListItemText primary={chapter} />
</ListItem>
)
})
return (
<List
component="nav"
aria-labelledby="nested-list-subheader"
subheader={
<ListSubheader component="div" id="nested-list-subheader">
</ListSubheader>
}
className={classes.root}
>
<ListItem button onClick={handleClick}>
<ListItemText primary={unitName} />
{!open ? <ExpandLess /> : <ExpandMore />}
</ListItem>
<Collapse in={!open} timeout="auto" unmountOnExit>
<List component="div" disablePadding className={classes.selected}>
{dropDownUnit}
</List>
</Collapse>
</List>
);
}
Стиль Psudo — чего я пытаюсь достичь
<DropDownMenu>
<MenuItem> // Suppose this is selected
<MenuItem>
<DropDownMenu>
<MenuItem> // onClick --> Select this and deselect all other selected buttons
Ответ №1:
У вас может быть родительский элемент этих компонентов, чтобы родительский элемент сохранял состояние того, кто активен. Таким образом, вы можете передать это состояние и установщик состояния в качестве реквизита, чтобы все знали, кто активен
export default function App() {
const [selectedItem, setSelectedItem] = React.useState();
return (
<>
<DropDownMenu
selectedItem={selectedItem} // pass down as props
setSelectedItem={setSelectedItem} // pass down as props
unit={...}
chooseChapter={function () {}}
/>
...
Для дочерних элементов просто реорганизуйте Призыв к действию (в данном случае onClick
), чтобы установить состояние, используя переданные реквизиты. Обратите внимание на selected
реквизит ListItem
, теперь мы используем состояние, которое мы передали от родительского
let dropDownUnit = chapterList.map((chapter, index) => {
return (
<ListItem
button
className={classes.selected}
selected={props.selectedItem === chapter}
onClick={() => props.setSelectedItem(chapter)}
key={index}
>
<ListItemText primary={chapter} />
</ListItem>
);
});
Комментарии:
1. Да, хотя мне пришлось немного подправить код, чтобы он соответствовал моей специфике, это помогло мне понять, что мне нужно сделать, чтобы заставить его работать. Спасибо!