简体   繁体   中英

How to change icons image when active in NavLink?

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.

  1. isActive should return a boolean value if the current link should be active or not, the useState state updater functions are void returns.
  2. Don't use a single boolean state value, this will toggle all icons if they all use the same condition.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM