'Change component upon clicking a button
I'm a beginner in react. Let's say there is a bell icon for notifications. Once clicked, there will be a summary of recently received notifications and below, there is a button. When I click that button, I want to replace the recent notifications component with a list containing past notifications without having the need to go to different pages. How can I implement the onClick handler on the initial button? Should I use react-router?
Notif.jsx (recent notifs)
import * as React from 'react';
import Button from '@mui/material/Button';
import Menu from '@mui/material/Menu';
import MenuItem from '@mui/material/MenuItem';
export default function BasicMenu() {
const [anchorEl, setAnchorEl] = React.useState(null);
const open = Boolean(anchorEl);
const handleClick = (event) => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
return (
<div>
<Button
id="basic-button"
aria-controls={open ? 'basic-menu' : undefined}
aria-haspopup="true"
aria-expanded={open ? 'true' : undefined}
onClick={handleClick}
>
<img className="icons" src="notif-icon.png" />
</Button>
<Menu
id="basic-menu"
anchorEl={anchorEl}
open={open}
onClose={handleClose}
MenuListProps={{
'aria-labelledby': 'basic-button',
}}
>
<Button variant="contained"> See all notifs </Button> *// once clicked, it will show the full list of notifs w/o redirecting to another page*
<MenuItem onClick={handleClose}>notif 1</MenuItem>
<MenuItem onClick={handleClose}>notif 1</MenuItem>
<MenuItem onClick={handleClose}>notif 1</MenuItem>
</Menu>
</div>
);
}
FullList.jsx (Full history of notifs)
import * as React from 'react';
import Divider from '@mui/material/Divider';
import Paper from '@mui/material/Paper';
import MenuList from '@mui/material/MenuList';
import MenuItem from '@mui/material/MenuItem';
import ListItemText from '@mui/material/ListItemText';
import ListItemIcon from '@mui/material/ListItemIcon';
import Typography from '@mui/material/Typography';
import ContentCut from '@mui/icons-material/ContentCut';
import ContentCopy from '@mui/icons-material/ContentCopy';
import ContentPaste from '@mui/icons-material/ContentPaste';
import Cloud from '@mui/icons-material/Cloud';
export default function IconMenu() {
return (
<Paper sx={{ width: 320, maxWidth: '100%' }}>
<MenuList>
<MenuItem>
<ListItemText>notif 1</ListItemText>
</MenuItem>
<MenuItem>
<ListItemText>notif 2</ListItemText>
</MenuItem>
<MenuItem>
<ListItemText>notif 3</ListItemText>
</MenuItem>
<MenuItem>
<ListItemText>notif 4</ListItemText>
</MenuItem>
</Paper>
);
}
Solution 1:[1]
You can do optional rendering 3 different ways. You can either use conditoinal rendering using the && operator like this: a && <B /> in this case if a is true, then B is rendered.
You can also use a ternary operator a ? <B /> : <C /> Which will render either B or C where a is true and false respectively
And you can use react-router-dom (or others) to route the entire window location to render a different page.
Here I am going to assume you just want to conditionally render a notification list or just generally conditional rendering.
Suppose you have the following code.
function MyComponent(props) {//React functional component
const [isClicked, setIsClicked] = React.useState(false); //Here I am using react hooks (since react 16).
function handleClick(e) => {
setIsClicked(true);
}//We pass this function into the buttons onClick method
return (
<div>
{!isCicked && <button id="notificationBtn" onClick={handleClick} />}
{isClicked && <NotificationList />}
</div>
)
}
In this example the NotificationList is a component that has your notification code to list all notifications etc as you mentioned...
using the && operator will either render the componnt or it won't. Another way we could have written this code is using a ternary operator... It would have looked like this inside the div{!isClicked ? <button id="notificationBtn" onClick={handleClick} /> : <NotificationList />}
Please note you do have to wrap any jsx that has more inner jsx appearing in parenthesis as you would normally do. Such as:{isClicked && (<div><span>Children</span><button>Click me</button></div>)}
I hope this makes sense how we can take advantage of these 2 methods of conditional rendering (the one where we optionally render a component and the other where we render something or something else (ternary)).
If you would rather navigate the entire window (for flow control, etc) then react-router-dom is what you are looking for. Here is a tutorial on how to use it.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
