¿Cómo puedo alternar el menú del cajón dentro de SideMenu.js
desde el botón NavBar.js
?
NavBar.js
const NavBar = () => { return ( <AppBar> <AppBarSection> <button onClick={toggleDrawerMenuHere}></button> </AppBarSection> </AppBar> ); }; export default NavBar;
El botón está ubicado en NavBar.js
, que quiero alternar DrawerMenu de SideMenu.js
.
SideMenu.js
const SideMenu = (props) => { const [expanded, setExpanded] = React.useState(true); const handleClick = () => { setExpanded(!expanded); }; const onSelect = (e) => { props.history.push(e.itemTarget.props.route); }; const setSelectedItem = (pathName) => { let currentPath = items.find((item) => item.route === pathName); if (currentPath.text) { return currentPath.text; } }; return ( <> <Drawer expanded={expanded} position='start' mode='push' mini={true} items={items.map((item, index) => ({ ...item, selected: index === setSelectedItem }))} onSelect={onSelect}> <DrawerContent> <button className="k-button" onClick={handleClick}>Toggle the DrawerMenu</button> </DrawerContent> </Drawer> </> ); }; export default withRouter(SideMenu);
Botón original para alternar DrawerMenu en SideMenu.js
.
No especificó en la pregunta, pero supongo que los componentes SideMenu y NavBar son hermanos.
por ejemplo, suponiendo que se representen dentro del componente de la aplicación.
Aplicación.js
const App = () => { const [expanded, setExpanded] = React.useState(true); const handleClick = () => { setExpanded(!expanded); }; return ( <NavBar expanded={expanded} /> <SideMenu onExpandDrawerMenu={handleClick} /> ); }
Basado en esto, SideMenu recibirá onExpandDrawerMenu prop, que es una función a la que puede llamar para modificar expandida. Y expandido se pasa a NavBar como accesorio. Entonces, esta solución se basa en mover el estado a un componente superior para pasarlo a ambos niños. Otra forma de hacerlo sin mover el estado hacia arriba es usando redux, pero eso sería una exageración para esta situación.
No necesita llamar a la función en sí, todo lo que desea es actualizar el estado para abrir/cerrar el cajón.
Entonces, la respuesta es mover su estado expandido hacia arriba en su árbol React.
o muévete
const [expanded, setExpanded] = React.useState(true); const handleClick = () => { setExpanded(!expanded); };
al primer padre en común de ambos archivos y pase expandido y handleClick como accesorios.
const SideMenu = (props) => { const onSelect = (e) => { props.history.push(e.itemTarget.props.route); }; const setSelectedItem = (pathName) => { let currentPath = items.find((item) => item.route === pathName); if (currentPath.text) { return currentPath.text; } }; return ( <> <Drawer expanded={props.expanded} position='start' mode='push' mini={true} items={items.map((item, index) => ({ ...item, selected: index === setSelectedItem }))} onSelect={onSelect}> <DrawerContent> <button className="k-button" onClick={props.toggleDrawer}>Toggle the DrawerMenu</button> </DrawerContent> </Drawer> </> ); }; export default withRouter(SideMenu); const NavBar = (props) => { return ( <AppBar> <AppBarSection> <button onClick={props.toggleDrawer}></button> </AppBarSection> </AppBar> ); }; export default NavBar;
O si su padre común está "ausente" (sus hijos están demasiado profundos en el árbol), también puede crear un contexto usando useContext, almacenando su estado y la función de alternar. Entonces puedes usarlo donde no puedas
const SideMenu = (props) => { const { expanded, toggleDrawer } = React.useContext(MenuContext); const onSelect = (e) => { props.history.push(e.itemTarget.props.route); }; const setSelectedItem = (pathName) => { let currentPath = items.find((item) => item.route === pathName); if (currentPath.text) { return currentPath.text; } }; return ( <> <Drawer expanded={expanded} position='start' mode='push' mini={true} items={items.map((item, index) => ({ ...item, selected: index === setSelectedItem }))} onSelect={onSelect}> <DrawerContent> <button className="k-button" onClick={toggleDrawer}>Toggle the DrawerMenu</button> </DrawerContent> </Drawer> </> ); }; export default withRouter(SideMenu); const NavBar = () => { const { toggleDrawer } = React.useContext(MenuContext); return ( <AppBar> <AppBarSection> <button onClick={toggleDrawer}></button> </AppBarSection> </AppBar> ); }; export default NavBar;