Search code examples
javascriptreactjsnext.jstailwind-css

Tailwind CSS only some classes get applied when mapping dynamically in ReactJS


I'm writing a React component for a navbar of a personal site. I am using a list called navItems to track the name, color, and link for each navbar item:

const navItems = [
  {
    name: "home",
    color: "sky-700",
    link: "/"
  },
  {
    name: "bio",
    color: "green-500",
    link: "/bio"
  },
  {
    name: "blog",
    color: "yellow-300",
    link: "/blog"
  },
]

I then have a Navbar component to render onto the rest of the page, using navItems.map to transform the list into several Links, using a separate constant cl to construct the CSS I want for each Link:

export function Navbar() {
  return (
    <aside className="-ml-[8px] mb-16 tracking-tight">
      <div className="lg:sticky lg:top-20">
        <nav
          className="flex flex-row items-start relative px-0 pb-0 fade md:overflow-auto scroll-pr-6 md:relative"
          id="nav"
        >
          <div className="flex flex-row space-x-0 pr-10">
            {navItems.map(navItem => {
              const cl = `transition-all text-${navItem.color} flex align-middle relative py-1 px-2 m-1`

              return (
                <Link
                  key={navItem.link}
                  href={navItem.link}
                  className={cl}
                >
                  {navItem.name}
                </Link>
              )
            })}
          </div>
        </nav>
      </div>
    </aside>
  )
}

It seems to render fine, but the rendered components do not have colors displayed.

Strangely, if I add an unused constant next to cl with the name of the color attribute, it will start displaying that particular color correctly (and the rest unchanged), e.g.:

{navItems.map(navItem => {
              const unused = "text-green-500"
              const cl = `transition-all text-${navItem.color} flex align-middle relative py-1 px-2 m-1`

              return (
                <Link
                  key={navItem.link}
                  href={navItem.link}
                  className={cl}
                >
                  {navItem.name}
                </Link>
              )
            })}
...

Anyone have any idea why this is behaving like this?

Tried to populate CSS into React Links dynamically. Expected the CSS to render on the page, but it did not.


Solution

  • Problem :

    Tried to populate CSS into React Links dynamically. Expected the CSS to render on the page, but it did not.

    Cause :

    Use full classNames instead of joining them as string,

    • Tailwind extracts class names is that it will only find classes that exist as complete unbroken strings in your source files. If you use string interpolation or concatenate partial class names together, Tailwind will not find them and therefore will not generate the corresponding CSS. [1]

    Solution :

    Update navItems :

    const navItems = [
      {
        name: "home",
        color: "text-sky-700",
        link: "/"
      },
      {
        name: "bio",
        color: "text-green-500",
        link: "/bio"
      },
      {
        name: "blog",
        color: "text-yellow-300",
        link: "/blog"
      },
    ]
    

    And inside map function, update cl :

    const cl = `transition-all ${navItem.color} flex align-middle relative py-1 px-2 m-1`
    

    Please Read :