How can I toggle Drawer Menu inside SideMenu.js
from NavBar.js
button?
NavBar.js
const NavBar = () => {
return (
<AppBar>
<AppBarSection>
<button onClick={toggleDrawerMenuHere}></button>
</AppBarSection>
</AppBar>
);
};
export default NavBar;
Button is located in NavBar.js
which I want to toggle DrawerMenu from 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);
Original button to toggle DrawerMenu in SideMenu.js
.
You didn't specify in the question but I'm assuming that SideMenu and NavBar components are siblings.
e.g assuming they're being rendered inside the App component.
App.js
const App = () => {
const [expanded, setExpanded] = React.useState(true);
const handleClick = () => {
setExpanded(!expanded);
};
return (
<NavBar expanded={expanded} />
<SideMenu onExpandDrawerMenu={handleClick} />
);
}
Based on this SideMenu will receive onExpandDrawerMenu prop which is a function you can call to modify expanded. And expanded is passed to NavBar as a prop. So this solution is based on moving the state to higher component to pass it down to both children. Another way you could do it without moving the state up is using redux - but that would be a overkill for this situation
You don't need to call the function itself, all you want is to update the state to get the Drawer open/closed.
So the answer it's to move your expaded state up in your React tree.
Either move
const [expanded, setExpanded] = React.useState(true);
const handleClick = () => {
setExpanded(!expanded);
};
to the first parent in common of both files and pass expanded and handleClick as props.
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;
Or if you common parent is "away" (your childs are to deep in the tree) you could also create a context using useContext, storing your state and the toggle function. Then u can use it wherever u cant
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;