Reputation: 139
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.
Upvotes: 3
Views: 8096
Reputation: 1001
First, you'll need to do a few things.
main
Dashboard
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
Upvotes: 4