DEV Community

Cover image for Como deixar componentes React mais organizados mesmo com Tailwind CSS?!
Carlos Eduardo Ramos
Carlos Eduardo Ramos

Posted on

Como deixar componentes React mais organizados mesmo com Tailwind CSS?!

Contexto

Muito se discute sobre as melhores formas de escrever CSS usando React. Por existirem diversas possibilidades (frameworks diferentes, CSS-in-JS, SASS, ...) as opiniões costumam ser divergentes.
Após a recente atualização na documentação do React, o Next.js (Next.js é um framework React full-stack) passou a ser indicado como uma das principais maneiras de se iniciar um projeto React.

Seguindo a própria documentação do Next.js, podemos ver que o Tailwind é uma ótima opção para ser utilizada para estilização:

Tailwind CSS is a utility-first CSS framework that works exceptionally well with Next.js.

As maiores críticas que costumo ver ao Tailwind são:

  • Deixa o HTML "sujo";
  • Não pode ser reaproveitado, gerando muita repetição de código.

Homem falando "Blah blah blah"

Conteúdo

Após estudar um pouco sobre CSS Modules e Vanilla Extract, percebi que podemos utilizar a "mesma ideia" de organização para tornar o Tailwind mais agradável e manutenível.

Para isso, vou usar de exemplo a refatoração de um pequeno componente de uma Navbar.

Badge escrito "Don't"

function NavbarUnorganized () {
  return (
    <nav className="flex flex-col lg:flex-row lg:px-48 gap-8 lg:gap-0  py-5 border-b-2 border-green-600 items-center justify-between bg-backgroundWhite">
      <a href="/">
        <img className="w-[125px]" src="#" alt="Logo da Nav de Exemplo." />
      </a>
      <ul className="flex flex-col md:flex-row gap-2 md:gap-8 font-kalam">
          <li><a href="/" className='text-green-600 text-xl lg:text-2xl navlink'>Home</a></li>
          <li><a href="/produtos" className='text-green-600 text-xl lg:text-2xl navlink'>Produtos</a></li>
          <li><a href="/contato" className='text-green-600 text-xl lg:text-2xl navlink'>Contato</a></li>
          <li><a href="/carrinho" className="flex items-center gap-2 text-green-600 text-xl lg:text-2xl navlink">Carrinho</a></li>
      </ul>
    </nav>
  );
}
Enter fullscreen mode Exit fullscreen mode

Nesse caso, temos um componente simples, sem lógica associada. Mesmo assim podemos perceber a dificuldade de dar manutenção em um código assim. Se precisarmos alterar os estilos da lista, teríamos que ir em item por item.

Badge escrito "Do"

Podemos melhorar isso simplesmente criando um arquivo JS para armazenar os estilos em variáveis:

//index.css.js
export const container = "flex flex-col lg:flex-row lg:px-48 gap-8 lg:gap-0  py-5 border-b-2 border-fontPurple items-center justify-between bg-backgroundWhite"

export const ul = "flex flex-col md:flex-row gap-2 md:gap-8 font-kalam"

export const navLink = "text-green-600 text-xl lg:text-2xl navlink"
Enter fullscreen mode Exit fullscreen mode

Agora podemos importar essas variáveis em nosso componente e utilizá-la em nossas classes, tornando-o bem mais legível:

//index.jsx
import {
    container,
    ul,
    navLink } from "./index.css";

function NavbarOrganized () {
    return (
        <nav className={container}>
          <a href="/">
            <img className="w-[125px]" src={'https://http.cat/202'} alt="Logo da Nav de Exemplo." />
          </a>
          <ul className={ul}>
              <li><a href="/" className={navLink}>Home</a></li>
              <li><a href="/produtos" className={navLink}>Produtos</a></li>
              <li><a href="/contato" className={navLink}>Contato</a></li>
              <li><a href="/carrinho" className={navLink}>Carrinho</a></li>
          </ul>
        </nav>
      )
}
Enter fullscreen mode Exit fullscreen mode

Dica extra

Placa escrito "Bônus"
Pelo fato do nosso index.css.js ser um arquivo Javascript, podemos também utilizar interpolações para extrair padrões de texto (conjunto de classes). Por exemplo com padrões que se repetem com frequência como flex-containers, poderíamos passar disso:

export const container = "flex flex-col items-center justify-between lg:flex-row lg:px-48 gap-8 lg:gap-0  py-5 border-b-2  bg-backgroundWhite"

export const ul = "flex flex-col items-center justify-between md:flex-row gap-2 md:gap-8 font-kalam"

export const navLink = "text-green-600 text-xl lg:text-2xl navlink"
Enter fullscreen mode Exit fullscreen mode

Para algo mais simples:

const flexCol = "flex flex-col items-center justify-between" 

export const container = `${flexCol}  lg:flex-row lg:px-48 gap-8 lg:gap-0  py-5 border-b-2  bg-backgroundWhite`

export const ul = `${flexCol} md:flex-row gap-2 md:gap-8 font-kalam`

export const navLink = "text-green-600 text-xl lg:text-2xl navlink"
Enter fullscreen mode Exit fullscreen mode

Como esse tipo de padrão se repete muito ao longo de um projeto, talvez você queira armazenar esses conjuntos de classes em um arquivo global, fora do componentes.

Conclusão

Existem diversas maneiras de tornar o uso do Tailwind mais simples e de aproveitar o reuso dos estilos.
Alguns recursos são nativos e estão na própria documentação (como a extração de classes com o uso do @apply, criação de um componente, uso de loops, etc).

Mas atualmente tenho gostado bastante de extrair como string (em vez de usar @apply), pois é mais rápido/prático.

Top comments (1)

Collapse
 
sucodelarangela profile image
Angela Caldas

Fantástico, Carlos! Adorei as dicas de organização, talvez até dê uma chance ao Tailwind num próximo projeto e, caso positivo, já vou aplicar essas dicas <3