Creating Routes in React - reactjs

I created my drawer using Materials UI and now I can't create links to other pages.I tried to set the link to https://www.google.com/ also.But it also didn't work.
Below is the part of my code.
<List
component="nav"
aria-labelledby="nested-list-subheader"
className={classes.menu}
>
<ListItem button>
<ListItemText primary="Buses" component={Link} to="/buses" />
</ListItem>
<ListItem button>
<ListItemText primary="Condutors" />
</ListItem>
<ListItem button onClick={handleClick}>
<ListItemText primary="Reports" />
{open ? <ExpandLess /> : <ExpandMore />}
</ListItem>
<Collapse in={open} timeout="auto" unmountOnExit>
<List component="div" disablePadding>
<ListItem button className={classes.nested}>
<ListItemText primary="Generate Report" />
</ListItem>
<ListItem button className={classes.nested}>
<ListItemText primary="View Report" />
</ListItem>
<ListItem button>
<ListItemText primary="Profle" />
</ListItem>
<ListItem button>
<ListItemText primary="Log Out" />
</ListItem>
</List>
</Collapse>
</List>```

You can use Link for react-router-dom its like a in html
or if Is for page in tour web, you can use useHistory the same module

From react-router-dom documentation:
Provides declarative, accessible navigation around your application.
You can use the normal <a><a/> HTML tag for referring to external links.

Related

Change component alignment in react mui, ListItemIcon

Default direction of ListItemIcon is ltr and it start from left to right.
How can I change the default behaviour ?
Any idea apperciate.
code snipped :
<ListItem disablePadding>
<ListItemButton>
<ListItemIcon>
{<CloseIcon style={{ direction: "rtl" }} />}
</ListItemIcon>
</ListItemButton>
</ListItem>
Try like this.
<ListItem>
<ListItemText primary="Hello" />
<IconButton edge="end">
<CloseIcon />
</IconButton>
</ListItem>
You can specify how you want to align you items in the ListItemIcon like this:
<ListItem disablePadding>
<ListItemButton>
<ListItemIcon sx={{justifyContent: 'right'}}>
{<CloseIcon />}
</ListItemIcon>
</ListItemButton>
</ListItem>

React material ui nested list collapse does not work

I have a nested data. When I press parent data, I want subdata to appear under it. My code is as below.
<List>
{data1.map((task, index)=>(
<ListItem>
<ListItemButton onClick={() => handleClick(task.name)}>
<ListItemText key={index} primary={task.name}/>
</ListItemButton>
{task.subdata.map((child, i)=>(
<Collapse unmountOnExit in={open === task.name}>
<List>
<ListItemButton >
<ListItemText primary={child.name}/>
</ListItemButton>
</List>
</Collapse>
))}
</ListItem>
))}
</List>
screenshot is as below.

When i click one button its open all buttons simultaneously

When I click on the post button it opens all buttons like media and user .i tried to define state function but when i click one button all buttons are open simultaneously.
this problem i am facing
My code are here
export default function ListItem() {
const [open, setOpen] = React.useState(false);
const handleClick = () => {
setOpen(!open);
};
return (
<div>
<List
sx={{ width: '100%', maxWidth: 360, bgcolor: 'background.paper' }}
component="nav"
aria-labelledby="nested-list-subheader"
>
{/* dashbord */}
<ListItemButton component="a" href="#simple-list">
<ListItemIcon>
<DashboardTwoToneIcon />
</ListItemIcon>
<ListItemText primary="DashBoard" />
</ListItemButton>
{/* post */}
<ListItemButton onClick={handleClick}>
<ListItemIcon>
<PostAddTwoToneIcon />
</ListItemIcon>
<ListItemText primary="Post" />
{open ? <ExpandLess /> : <ExpandMore />}
</ListItemButton>
<Collapse in={open} timeout="auto" unmountOnExit>
<List component="div" disablePadding>
<ListItemButton sx={{ pl: 4 }} component="a" href="#">
<ListItemText primary="New post" component="a" />
</ListItemButton>
<ListItemButton sx={{ pl: 4 }} component="a" href="#">
<ListItemText primary="All posts" />
</ListItemButton>
</List>
</Collapse>
{/* Media */}
<ListItemButton onClick={handleClick}>
<ListItemIcon>
<SubscriptionsTwoToneIcon />
</ListItemIcon>
<ListItemText primary="Media" />
{open ? <ExpandLess /> : <ExpandMore />}
</ListItemButton>
<Collapse in={open} timeout="auto" unmountOnExit>
<List component="div" disablePadding>
<ListItemButton sx={{ pl: 4 }} component="a" href="#">
<ListItemText primary="All Media" component="a" />
</ListItemButton>
<ListItemButton sx={{ pl: 4 }} component="a" href="#">
<ListItemText primary="Add New Media" />
</ListItemButton>
</List>
</Collapse>
You are using a single boolean state for all of them. I suggest storing the open status of each item/element you want to toggle in an object and check if the specific item/element is currently toggled open.
const [open, setOpen] = React.useState({});
const handleClick = (id) => () => {
setOpen(open => ({
...open,
[id]: !open[id],
}));
};
...
<ListItemButton onClick={handleClick("post")}> // <-- pass id
<ListItemIcon>
<PostAddTwoToneIcon />
</ListItemIcon>
<ListItemText primary="Post" />
{open["post"] ? <ExpandLess /> : <ExpandMore />} // <-- check by id
</ListItemButton>
<Collapse
in={open["post"]} // <-- check by id
timeout="auto"
unmountOnExit
>
<List component="div" disablePadding>
<ListItemButton sx={{ pl: 4 }} component="a" href="#">
<ListItemText primary="New post" component="a" />
</ListItemButton>
<ListItemButton sx={{ pl: 4 }} component="a" href="#">
<ListItemText primary="All posts" />
</ListItemButton>
</List>
</Collapse>
Apply same for other buttons and collapsables but using specific unique keys.
You call function setOpen on a click on any object, however setOpen seems to change the state of a global variable that is used to determine whether the contents should be shown or not. Try to set a unique variable as open state for every button and only change this variable with a function in onClick

How to open a selected nested list on Material-UI?

I have a code in React where I have two list menus that have nested menus.
class Nav extends React.Component {
state = { open: false };
handleClick = () => {
this.setState({ open: !this.state.open });
};
render() {
const { classes } = this.props;
return (
<div className={classes.root}>
<List
component="nav"
>
<ListItem button onClick={this.handleClick}>
<ListItemText primary="Files" />
{this.state.open ? <ExpandLess /> : <ExpandMore />}
</ListItem>
<Collapse in={this.state.open} timeout="auto" unmountOnExit>
<List component="div" disablePadding>
<ListItem button className={classes.nested}>
<ListItemText primary="Providers" />
</ListItem>
<ListItem button className={classes.nested}>
<ListItemText primary="Insurance Companies" />
</ListItem>
</List>
</Collapse>
<ListItem button onClick={this.handleClick}>
<ListItemText primary="Utilities" />
{this.state.open ? <ExpandLess /> : <ExpandMore />}
</ListItem>
<Collapse in={this.state.open} timeout="auto" unmountOnExit>
<List component="div" disablePadding>
<ListItem button className={classes.nested}>
<ListItemText primary="Excel Templates" />
</ListItem>
<ListItem button className={classes.nested}>
<ListItemText primary="Upload File" />
</ListItem>
</List>
</Collapse>
</List>
</div>
);
}
}
When I click the first menu, the second menu also opens. How do I only open one menu and the other one remains closed?
I think you will need to have two seperate values in state in order to only open one at a time
state = { openMenu1: false, openMenu2: false }
And the click events should trigger only one of those to go to true/false.
Make sure to change the variable in the Collapse component to use the corresponding state as well

Render component in Drawer with Material-ui Lists

This feels like it should be self-explanatory in the Docs, but they abstract out a key part of the List code to another file and don't show it. So, I'm left asking you fine folks.
I'm looking to do something pretty simple: Use a List-based sidebar with Material-ui (beta-version) to render a component in a Drawer. I have the list setup, but I can't figure out how to make the ListItems link to the components and perform the render. Here's my code:
class DashboardScreen extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div className={this.props.classes.container}>
<Appbar pagetitle="Dashboard" />
<div className={this.props.classes.appFrame}>
<Drawer
type="permanent"
classes={{
paper: this.props.classes.drawerPaper,
}}
anchor="left">
<div className={this.props.classes.drawerHeader} />
<List>
<ListItem button>
<ListItemIcon>
<AssessmentIcon />
</ListItemIcon>
<ListItemText primary="Analytics"/>
</ListItem>
<ListItem button>
<ListItemIcon>
<ImportContactsIcon />
</ListItemIcon>
<ListItemText primary="Create Investigation"/>
</ListItem>
<ListItem button>
<ListItemIcon>
<AssignmentIcon />
</ListItemIcon>
<ListItemText primary="Create Survey"/>
</ListItem>
<ListItem button>
<ListItemIcon>
<AssignmentTurnedInIcon />
</ListItemIcon>
<ListItemText primary="Create Response"/>
</ListItem>
<ListItem button>
<ListItemIcon>
<SettingsIcon />
</ListItemIcon>
<ListItemText primary="Settings"/>
</ListItem>
</List>
</Drawer>
<main className={this.props.classes.content}>
Testing Stuff!
</main>
</div>
</div>
)
}
}
What I'm rendering is just another separate component called "Analytics". There's nothing special about it. How do I get the first ListItem, with text = "Analytics", render said component <Analytics />?
The ListItem will have an onClick property that it propagates through to the appropriate child components. So, if you're searching to receive clicks for each ListItem, you can simply do this:
<ListItem button onClick={() => alert("Hey buddy this will alert when clicked.")}>
<ListItemIcon>
<AssessmentIcon />
</ListItemIcon>
<Analytics />
</ListItem>
<ListItem button onClick={() => alert("This is a click on a different item.")}>
<ListItemIcon>
<ImportContactsIcon />
</ListItemIcon>
<Analytics />
</ListItem>
The propagation of props down to the appropriate area is described at the bottom of the props section on the ListItem API page.
Solved!
Here's my code:
class DashboardScreen extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div className={this.props.classes.container}>
<Appbar pagetitle="Dashboard" />
<div className={this.props.classes.appFrame}>
<Drawer
type="permanent"
classes={{
paper: this.props.classes.drawerPaper,
}}
anchor="left">
<div className={this.props.classes.drawerHeader} />
<List>
<ListItem button component={({...props}) => <Link to={this.props.match.url + '/analytics'} {...props} />}>
<ListItemIcon>
<AssessmentIcon />
</ListItemIcon>
<ListItemText primary="Analytics"/>
</ListItem>
<ListItem button>
<ListItemIcon>
<ImportContactsIcon />
</ListItemIcon>
<ListItemText primary="Create Investigation"/>
</ListItem>
<ListItem button>
<ListItemIcon>
<AssignmentIcon />
</ListItemIcon>
<ListItemText primary="Create Survey"/>
</ListItem>
<ListItem button>
<ListItemIcon>
<AssignmentTurnedInIcon />
</ListItemIcon>
<ListItemText primary="Create Response"/>
</ListItem>
<ListItem button>
<ListItemIcon>
<SettingsIcon />
</ListItemIcon>
<ListItemText primary="Settings"/>
</ListItem>
</List>
</Drawer>
<main className={this.props.classes.content}>
<Route path={this.props.match.url + "/analytics"} component={Analytics}/>
</main>
</div>
</div>
)
}
}
Essentially, you need to contain the Route for the component within the main section of the Drawer. Then, you need to Link to that route via the component wrapped within the component prop on the ListItem.
Hope this helps somebody!
Did you try to simply change ListItemText with your custom component?
<ListItem button>
<ListItemIcon>
<AssessmentIcon />
</ListItemIcon>
<Analytics />
</ListItem>

Resources