Search code examples
javascriptreactjsreact-routerstyled-components

How to get parent props in child component when using styled component in react


Let me illustrate with an examble

//NavLink: react router component

const StyledNavLink = styled(NavLink)`
  color: red;
  background: blue;
`
function styledLink(label, to) {
  return <StyledNavLink
    to={to}
    className={(props) => console.log(props)}
  >
    {label}
  </StyledNavLink>
}

Here nothing is printed... If I use NavLink instead of StyledNavLink, I get all the prop values in console. Then how to get NavLink properties in StyledNavLink component?


Solution

  • Issue

    The className prop of the NavLink component is conflicting with the className prop used by styled-components. The styled(NavLink) component will only ever have a stringified className prop whereas the NavLink component can take either a string or function className value.

    Solution

    Pass the NavLink className prop under a different prop and handle the conditional logic in the styled component.

    Example:

    const StyledNavLink = styled(({ className, navLinkClassName, ...props }) => (
      <NavLink
        {...props}
        className={(props) => {
          let extraClass =
            typeof navLinkClassName === "function"
              ? navLinkClassName(props)
              : navLinkClassName;
          return [className, extraClass].filter(Boolean).join(" ");
        }}
      />
    ))`
      color: red;
      background: blue;
    
      &.activeLink {
        color: green;
        background: lightgreen;
      }
    `;
    

    Usage:

    function styledLink(label, to) {
      return (
        <StyledNavLink
          to={to}
          navLinkClassName={(props) => {
            console.log("styledLink", props);
            return props.isActive ? "activeLink" : null;
          }}
        >
          {label}
        </StyledNavLink>
      );
    }
    
    ...
    
    {styledLink("home", "/")}
    

    If you meant for styledLink to actually be a React component:

    function StyledLink({ label, to }) {
      return (
        <StyledNavLink
          to={to}
          navLinkClassName={(props) => {
            console.log("StyledLink", props);
            return props.isActive ? "activeLink" : null;
          }}
        >
          {label}
        </StyledNavLink>
      );
    }
    
    ...
    
    <StyledLink to="/" label="home" />
    

    Edit how-to-get-parent-props-in-child-component-when-using-styled-component-in-react

    enter image description here