javascriptreactjsreact-router-domtailwind-cssclassname

How can I use tailwind-css to style the active state of the Navlink(react-router-dom)?


I am trying to use a template literal for the className of the Navlink but it does not work.

This is current code:

className={`px-2 py-2.5 hover:bg-cprimary-300 hover:text-csecond-100 rounded-md transition ${({ isActive }) => isActive ? "bg-red-500" : "bg-black-500"}`}

I tried using only the active part to check if anything else is messing with it but it still does not work.

className={`${({ isActive }) => isActive ? "bg-red-500" : "bg-blue-500"}`}

Is there something wrong with the way I am using the template literal?

It works when I use this:

className={({ isActive }) => isActive ? "bg-red-500" : "bg-blue-500"}

Solution

  • The className prop takes either a string or a function callback that is passed an isActive prop and returns a string or undefined.

    See NavLink

    declare function NavLink(
      props: NavLinkProps
    ): React.ReactElement;
    
    interface NavLinkProps
      extends Omit<
        LinkProps,
        "className" | "style" | "children"
      > {
      caseSensitive?: boolean;
      children?:
        | React.ReactNode
        | ((props: { isActive: boolean }) => React.ReactNode);
      className?:
        | string
        | ((props: { isActive: boolean; }) => string | undefined); // <--
      end?: boolean;
      style?:
        | React.CSSProperties
        | ((props: { isActive: boolean; }) => React.CSSProperties);
    }
    

    Use the callback function to accept the isActive prop and return a string containing the CSS classes you want to be applied.

    className={({ isActive }) => [
        "px-2 py-2.5",
        "hover:bg-cprimary-300 hover:text-csecond-100",
        "rounded-md transition",
        isActive ? "bg-red-500" : "bg-black-500"
      ].join(" ")
    }