Search code examples
reactjsreact-router-domstyled-components

Styled components React router v6


const StyledNavLink = styled(NavLink)`
  text-decoration: ${(props) => {
    console.log(props.style);
    return props.style ? (isActive) => (isActive ? "underline" : "none") : "none";
  }};
  &:hover {
    text-decoration: underline;
  }
`;

export default function BasicExample() {
  return (
    <Router>
      <Navbar>
        <NavItems>
          <NavItem>
            <NavLink
              to="/"
              end={true}
              style={({ isActive }) => {
                console.log(isActive + "About");
                return { textDecoration: isActive ? "underline" : "none" };
              }}
            >
              Home
            </NavLink>
          </NavItem>
          <NavItem>
            <NavLink
              to="/about"
              style={({ isActive }) => {
                console.log(isActive + "About");
                return { textDecoration: isActive ? "underline" : "none" };
              }}
            >
              About
            </NavLink>
          </NavItem>
          <NavItem>
            <NavLink
              to="/dashboard"
              style={({ isActive }) => {
                console.log(isActive + "Dashboard");
                return { textDecoration: isActive ? "underline" : "none" };
              }}
            >
              Dashboard
            </NavLink>
          </NavItem>
        </NavItems>
      </Navbar>
      <Routes>
        <Route path="/" caseSensitive={false} element={<Home />}></Route>
        <Route path="/about" caseSensitive={false} element={<About />}></Route>
        <Route path="/dashboard" caseSensitive={false} element={<Dashboard />}></Route>
      </Routes>
    </Router>
  );
}

How can I abstract out the logic for styling an active link to say the StyledNavLink styled component, I tried using StyledNavLink in place of Navlink but it doesn't work. I'm not sure what I might be missing. If I console out props.style within the StyledNavLink then it is always undefined.


Solution

  • const StyledNavLink = styled(NavLink)`
      text-decoration: ${(props) => {
        console.log(props.style);
        return props.style ? (isActive) => (isActive ? "underline" : "none") : "none";
      }};
      &:hover {
        text-decoration: underline;
      }
     &[aria-current] {
        color: red;
      }
    `;
    

    I just had to check if aria-current attribute was present and now if I replace NavLink with StyledNavLink every thing works as expected

    Or, as shown below, one can check for existence of the active class

    const StyledNavLink = styled(NavLink)`
        text-decoration: ${(props) => {
        console.log(props);
        return props.style ? (isActive) => (isActive ? "underline" : "none") : "none";
      }}; 
      &:hover {
        text-decoration: underline;
      }
     &[class*="active"] {
        color: red;
      }
    `;