In a React project, I have created menu which has some links as seen in the image below, I have also changed background color of link and color of text when active, but, I want to change icon image ie it would replace the icon image when active. So what could be the appropriate solution?
Below is the code for your reference:
<List>
{itemList.map((item, index) => {
return (
<ListItem
button
key={item.text}
onClick={() => {
setData(item.text);
}}
>
<NavLink
exact
to={item.link}
style={{ display: "flex", flexWrap: "wrap" }}
activeStyle={{ backgroundColor: "purple", color: "white" }}
>
{item.icon && (
<img
src={item.icon}
style={{ marginRight: "25px" }}
height="18px"
/>
)}
<ListItemText primary={item.text} />
</NavLink>
</ListItem>
);
})}
</List>
I have tried with following code:
const [newActiveLink, setNewActiveLink] = useState(false)
<NavLink
exact
to={item.link}
style={{ display: "flex", flexWrap: "wrap" }}
activeStyle={{ backgroundColor: "purple", color: "white" }}
isActive={(match, location) => match ? setNewActiveLink(true) : setNewActiveLink(false)}
>
...
{
newActiveLink == true ? {item.icon && (
<img
src={item.iconWhite}
style={{ marginRight: "25px" }}
height="18px"
/>
)} : {item.icon && (
<img
src={item.icon}
style={{ marginRight: "25px" }}
height="18px"
/>
)}
}
</NavLink>
But background color disappears when isActive is used
Find this codesandbox link: https://codesandbox.io/s/react-material-forked-3uuyg
I think you are close, just need a couple tweaks.
isActive
should return a boolean value if the current link should be active or not, the useState
state updater functions are void returns.Code:
const [newActiveLink, setNewActiveLink] = useState(null);
...
<NavLink
exact
to={item.link}
style={{ display: "flex", flexWrap: "wrap" }}
activeStyle={{ backgroundColor: "purple", color: "white" }}
isActive={(match, location) => {
match && setNewActiveLink(index); // <-- set active index
return match; // <-- return boolean
}}
>
{newActiveLink === index // <-- check active index against current index
? item.iconWhite && (
<img
src={item.iconWhite}
style={{ marginRight: "25px" }}
height="18px"
/>
)
: item.icon && (
<img
src={item.icon}
style={{ marginRight: "25px" }}
height="18px"
/>
)}
<ListItemText primary={item.text} />
</NavLink>
I just struggled through this problem and found an elegant solution without extra react state that applies to Material UI v5 components:
import { NavLink } from "react-router-dom"
import CottageIcon from "@mui/icons-material/Cottage"
<NavLink to="" aria-label="Home">
<CottageIcon
edge="start"
color="green"
sx={{
".active &": {
color: "red",
}
}}
/>
</NavLink>
The whole thing is that NavLink get the class name active
and I leveraged the CSS selectors of MUI sx
prop.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.