TypeError: l is not an function
SpencerIsTheKey opened this issue · 1 comments
I recently started a new personal project and decided to take the opportunity to learn Tailwind CSS after working with vanilla CSS for a while. I quickly found that it I was having to scroll horizontally to see all of my styles, and found that this library made my life much easier.
I then built the following components with it to create my navigation bar:
NavItem.tsx:
import tw from "tailwind-styled-components";
import { FunctionComponent } from "react";
type Props = {
text: string;
href: string;
active: boolean;
}
const NavItem: FunctionComponent<Props> = ({ text, href, active}) => {
const NavLink = tw.link`
text-base
relative
transition-all
duration-200
md:flex-row
md:w-fit
md:gap-24
md:items-center
md:before:absolute
md:before:w-0
md:before:h-6
md:before:-bottom-16
md:before:left-0
md:before:bg-black
md:before:transition-all
md:before:duration-200
hover:font-bold
${active ? "font-bold": "" }
`;
return(
<NavLink href={href}>
{text}
</NavLink>
);
}
export default NavItem;
NavBar.tsx:
import Link from "next/link";
import { useState } from "react";
import tw from "tailwind-styled-components";
import NavItem from "./NavItem";
const MENU_LIST = [
{text: "Home", href:"/"},
{text: "About", href: "/about"},
{text: "Contact", href: "/contact"},
{text: "Account", href: "/account"}
];
const NavBar = () => {
const [navActive, setNavActive] = useState(false);
const [activeIdx, setActiveIdx] = useState(-1);
const NavBarWrapper = tw.nav`
flex
h-20
p-16
justify-between
items-center
bg-primary
sticky
`;
const NavBurger = tw.div`
flex-col
gap-6
md:hidden
`;
const NavBurgerLayer = tw.div`
w-40
h-4
bg-black
rounded-sm
`;
const NavList = tw.div`
flex-col
fixed
top-60
w-56
gap-24
-right-56
py-24
px-16
transition-all
duration-200
${navActive ? "right-0" : ""}
`;
return(
<>
<header>
<NavBarWrapper>
<Link href="/" onClick={() => setActiveIdx(0)}>
<h1>TEMP LOGO</h1>
</Link>
<NavBurger
onClick={() => setNavActive(!navActive)}
>
<NavBurgerLayer/>
<NavBurgerLayer/>
<NavBurgerLayer/>
</NavBurger>
<NavList>
{MENU_LIST.map((menu, idx) => (
<div onClick={() => {
setActiveIdx(idx);
setNavActive(false);
}}
key={menu.text}
>
<NavItem active={activeIdx === idx} {...menu} />
</div>
))}
</NavList>
</NavBarWrapper>
</header>
</>
)
}
export default NavBar;
Once I added this to my layout, a runtime error occurred that was labelled TypeError: l is not a function
, with the trace showing an origin inside a tailwind-styled-components file. Two function calls into tailwind-styled-components, in fact
I've checked through all of my Tailwind classes to make sure that I'm not trying to use an invalid class, and the only thing I found that might have been complicating things was the md:before:
classes. I split the styled class to remove those modifiers like so:
import tw from "tailwind-styled-components";
import { FunctionComponent } from "react";
import Link from "next/link";
type Props = {
text: string;
href: string;
active: boolean;
}
const NavItem: FunctionComponent<Props> = ({ text, href, active}) => {
const NavLinkWrapper = tw.div`
text-base
relative
transition-all
duration-200
hover:font-bold
md:flex-row
md:w-fit
md:gap-24
md:items-center
${active ? "font-bold": "" }
`
const NavAnimation = tw.div`
hidden
md:absolute
md:w-0
md:h-6
md:-bottom-16
md:left-0
md:bg-black
md:transition-all
md:duration-200
`
return(
<NavLinkWrapper>
<Link href={href} >
{text}
</Link>
<NavAnimation />
</NavLinkWrapper>
);
}
export default NavItem;
But found no difference. I then removed the Tailwind classes from the styled components and applied them to regular HTML elements and found the issue to be resolved. I would really love to be able to use this for my project, but as it stands now it seems to simply not work
I also had this same problem, when passing a prop "directly" to the component, in your case the prop "active":
const NavLinkWrapper = tw.div`
text-base
relative
transition-all
duration-200
hover:font-bold
md:flex-row
md:w-fit
md:gap-24
md:items-center
${active ? "font-bold": "" }
`
Try passing it like this:
<NavLinkWrapper active={active}>
<Link href={href} >
{text}
</Link>
<NavAnimation />
</NavLinkWrapper>
🇧🇷 Tradução:
Pra quem teve o mesmo erro (igual a mim), provávelmente é porque a prop "active" está sendo passada diretamente para o comoponente criado com tw (primeiro exemplo), basta passar a prop para o componente como o segundo exemplo.