Home > database >  Encapsulate a NavLink component and style it with Styled Component
Encapsulate a NavLink component and style it with Styled Component

Time:05-11

I am trying to create a menu with hyperlinks from the react-rounter-dom library component NavLink and style it with styled component

I Created a component called Link which is where NavLink is so you don't repeat this same line of code multiple times, then pass this component to styled component to inherit its properties so you can apply styles to it.

but the styles are not being applied to my component

NavLink

import { NavLink as NavLinkReactRouterDom } from "react-router-dom";

const Link = function ({ to, children, ...props }) {
  return (
    <>
      <NavLinkReactRouterDom
        {...props}
        className={({ isActive }) =>
          // console.log(isActive)
          isActive ? "is-active" : undefined
        }
        to={to}
      >
        {children}
      </NavLinkReactRouterDom>
    </>
  );
};
export default Link;

sidebarStyled.js (css)

import styled from "styled-components";
import Link from "./NavLink";
//    NavLink
export const Prueba = styled(Link)`
  color: white;
  font-size: 50px;
  text-decoration: none;
  display: flex;
  justify-content: flex-start;
  align-items: stretch;
  flex-direction: row;

  &.is-active {
    color: green;
  }
`

Sidebar

const Sidebar = function () {
  return (
    <SidebarContainer>
      <LogoContainer>
        <img src={Logo} alt="Logo" />
      </LogoContainer>
      <h1>Sidebe Here</h1>
      <Divider />
      <Menu>
        <NavList>
          <NavItem>
            <Prueba to="/">
              <LinkIcon icon="typcn:home-outline" />
              Inicio
            </Prueba>
          </NavItem>
        </NavList>
      </Menu>
    </SidebarContainer>
  );
};
export default Sidebar;

enter image description here

CodePudding user response:

Issue

The className prop of the styled component, Prueba isn't passed through to the component it's attempting to style, the NavLinkReactRouterDom component. Or rather, it is passed implicitly when the props are spread into it, but NavLinkReactRouterDom is overriding and setting it's own className prop.

const Link = function ({ to, children, ...props }) {
  return (
    <>
      <NavLinkReactRouterDom
        {...props} // <-- styled-component className pass here
        className={({ isActive }) => // <-- overridden here!
          // console.log(isActive)
          isActive ? "is-active" : undefined
        }
        to={to}
      >
        {children}
      </NavLinkReactRouterDom>
    </>
  );
};

Solution

The solution is to merge the styled-component's className prop with the active classname used for the NavLinkReactRouterDom component.

Example:

const Link = function ({ to, children, className, ...props }) {
  return (
    <NavLinkReactRouterDom
      {...props}
      className={({ isActive }) =>
        [className, isActive ? "is-active" : null].filter(Boolean).join(" ")
      }
      to={to}
    >
      {children}
    </NavLinkReactRouterDom>
  );
};

Edit encapsulate-a-navlink-component-and-style-it-with-styled-component

enter image description here

CodePudding user response:

you may need to use Prueba, instead of Link. since you inherit the Link component, applied custom CSS and store it in the variable named Prueba.

hence import it in the sidebar.js file and use it there

refer: https://codesandbox.io/s/objective-smoke-1bflsh?file=/src/App.js

add

import 'Prueba' from sidebarStyled.js'

change

....
<Prueba to="/">
   <LinkIcon icon="typcn:home-outline" />
    Inicio
</Prueba>
....
  • Related