I am working on Dashboard design using React material-ui package. I have an App bar and a Drawer with a List of different items. When I click items in Drawer, I want to render the respective component inside the "main" tag of Drawer.
The App.js component is class-based. And I have functional component for all other routes and features.
import React, { useState } from "react";
import { makeStyles, useTheme } from '@material-ui/core/styles';
import { Link } from 'react-router-dom'
import { useAuthState } from '../contexts/AuthContext';
import InboxIcon from '@material-ui/icons/MoveToInbox';
import DraftsIcon from '@material-ui/icons/Drafts';
import {MenuItem, MenuList, ListItemIcon, ListItemText
, Drawer, ListItem, List, Divider, CssBaseline
, Paper, IconButton, Typography, AppBar, Toolbar
, Button, Input } from '@material-ui/core';
const drawerWidth = 200;
const useStyles = makeStyles(theme => ({
root: {
display: 'flex',
},
appBar: {
width: `calc(100% - ${drawerWidth}px)`,
marginLeft: drawerWidth,
},
menuButton: {
marginRight: theme.spacing(2),
fontSize: "16px",
color: "#fff",
},
hide: {
display: 'none',
},
drawer: {
width: drawerWidth,
flexShrink: 0,
},
drawerPaper: {
width: drawerWidth,
},
toolbar: theme.mixins.toolbar,
content: {
flexGrow: 1,
backgroundColor: theme.palette.background.default,
padding: theme.spacing(3),
},
title: {
flexGrow: 1,
fontSize: "18px",
},
LinkBar: {
},
SideBarFont: {
fontSize: "14px",
},
}));
export default function Dashboard(props) {
const classes = useStyles();
const theme = useTheme();
const { setUser } = useAuthState();
const [open, setOpen] = React.useState(false);
return (
<div className={classes.root}>
<CssBaseline />
<AppBar
className={classes.appBar}
position="fixed"
>
<Toolbar>
<Typography variant="h6" className={classes.title} noWrap>
Dashboard
</Typography>
<Button color="inherit">Logout</Button>
</Toolbar>
</AppBar>
<Drawer
className={classes.drawer}
variant="permanent"
anchor="left"
classes={{
paper: classes.drawerPaper,
}}
>
<div className={classes.toolbar} />
<Divider />
<List component="nav" aria-label="main mailbox folders">
<ListItem button>
<ListItemIcon>
<InboxIcon />
</ListItemIcon>
<ListItemText disableTypography className={classes.SideBarFont} primary="User" />
</ListItem>
<ListItem button>
<ListItemIcon>
<DraftsIcon />
</ListItemIcon>
<ListItemText disableTypography className={classes.SideBarFont} primary="Account" />
</ListItem>
<ListItem button>
<ListItemIcon>
<DraftsIcon />
</ListItemIcon>
<ListItemText disableTypography className={classes.SideBarFont} primary="Customer Support" />
</ListItem>
<ListItem component={Link} to="/inventory" button>
<ListItemIcon>
<DraftsIcon />
</ListItemIcon>
<ListItemText disableTypography className={classes.SideBarFont} primary="Inventory" />
</ListItem>
</List>
</Drawer>
<main className={classes.content}>
<div className={classes.toolbar} />
<h1>Hello</h1>
<Typography paragraph>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua. Rhoncus dolor purus non enim praesent elementum
</Typography>
</main>
</div>
);
}
I have functional components for Users, Inventory, CustomerSupport, Account in their respective jsx files. How can i render or inside "main" when the user click on Drawer List items?
See below for the UI. I want to render where Hello is rendered.

First, you'll need to do a few things.
mainDashboard ComponentSince you are already using useState in your components, you'll need to set up another useState.
On your ListItem you can add an onClick to the component and do the useState function to set that state to a said component.
In the main you'll need to add some sort of ternary or checker to determine what component to display.
I have removed a number of items here but this is a brief example for you:
import User from '/path/to/user/component';
import Account from '/path/to/account/component';
...
export default function Dashboard(props) {
const [component, setComponent] = useState('user')
...
return (
...
<ListItem button onClick={() => setComponent('account')}>
<ListItemIcon>
<DraftsIcon />
</ListItemIcon>
<ListItemText disableTypography className={classes.SideBarFont} primary="Account" />
</ListItem >
...
<main className={classes.content}>
<div className={classes.toolbar} />
{
component === 'user' ?
<User />
:
component === 'account' ?
:
<Account />
...
}
</main>
</div>
);
}
Yes there is a cleaner way to do the component rendering in the main but this should give you an idea of where to start
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With