Do React ao Hotwire - Parte II - [PT-BR]
Tags: react, hotwire, rails, phlex
Published: 2024-06-16 15:44:26

[English version available](https://dev.to/cirdes/from-react-to-hotwire-part-ii-en-2lim)

## Introdução

No [primeiro artigo](https://dev.to/cirdes/do-react-ao-hotwire-parte-i-pt-br-1hm2) sobre essa migração do React para o Hotwire, eu abordei como chegamos à nossa stack atual em React. Nesta Parte II, vou falar sobre o retorno às views do Rails na Linkana.

## Evolução do Rails e o SSR

Uma das características mais brilhantes do Rails é sua obsessão pela simplicidade. Como o Rails nasceu dentro do [Basecamp](https://brasil.basecamp.com/), uma empresa que escolheu ter poucos funcionários, faz parte do DNA do Rails buscar maneiras de manter o desenvolvimento web simples. Por isso, o Rails é o [Framework de uma pessoa só](https://world.hey.com/dhh/the-one-person-framework-711e6318).

Ter participado da última edição do [Rails World](https://rubyonrails.org/world/2024) e assistido à palestra do [DHH](https://www.youtube.com/watch?v=iqXjGiQ_D-A) me fez perceber que gerar views no backend com Rails já não era mais sinônimo de interfaces lentas, feias e que não se preocupam com UX. Com Hotwire, através do Turbo e do Stimulus, era possível criar aplicações tão complexas como o Gmail, [Hey](https://hey.com/) ou Slack, [Campfire](https://once.com/campfire). E isso ficou ainda mais surreal com o [Turbo 8](https://evilmartians.com/chronicles/the-future-of-full-stack-rails-turbo-morph-drive).

<img width="100%" style="width:100%" src="https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExYnprZ2x6bjdudzZ1Y2NqOXlqdGVwMzZvY2ZhOGFlbDFpazdpOWJ0ZCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/vUvxwcgQ6Iqlm2p6g9/giphy.gif">

Mas o grande benefício do retorno ao Server Side Rendering (SSR) é não precisar de APIs. Criar uma API, seja ela REST ou GraphQL, torna o desenvolvimento mais lento. E não é apenas o Rails que está percebendo isso, é o Elixir com o Liveview, PHP com o [Livewire](https://livewire.laravel.com/docs/quickstart), e até mesmo o próprio JS com [HTMX](https://htmx.org/), além do próprio [React](https://react.dev/reference/react-dom/server). Como diz o Deno.js: [O Futuro (e o Passado) da Web é a Renderização do Lado do Servidor](https://deno.com/blog/the-future-and-past-is-server-side-rendering).

## Componentes vieram para ficar

Como vimos na Parte I desse artigo, views em React/Vue/Angular introduziram o conceito de componentes. Esses componentes são pequenos blocos de interface que condensam "Estilo (Tailwind)", "Estrutura (HTML)" e "Comportamento/JavaScript". Componentizar, além de promover o reuso e facilitar os testes, também facilita a customização. Mas o mais importante, eles já estão prontos. Você não precisa reinventar a roda. Um grande exemplo é o [Shadcn](https://ui.shadcn.com/), lançado apenas em março de 2023 e que já conta com 60k estrelas no Github.

Infelizmente, as views do Rails foram criadas no contexto pré-componentes. O html.erb é muito bom para se escrever HTML, mas não é bom para escrever comportamento. Já os partials são ótimos para se escrever comportamento, mas são péssimos para HTML.

Para tentar resolver isso, a primeira solução que surgiu foi o [ViewComponents](https://viewcomponent.org/), um framework criado pelo pessoal do Github. O ViewComponents é o nosso React, permitindo que o frontend seja pensado na forma de componentes. Ele é a solução mais popular hoje. Apesar de eu nunca ter usado, sinto que faltou ousadia. Ele me parece uma fusão dos partials com o erb. Mas o que mais me decepcionou foi que o [Gihub está migrando do Rails para o React](https://news.ycombinator.com/item?id=33576722) e os próprios mantenedores do ViewComponents [não me parecem muito empolgados](https://www.youtube.com/watch?v=YdeuXQJkZrs).

Como alternativa ao ViewComponents, encontrei o [Phlex](https://www.phlex.fun/). Ele vem com a ousadia de criar componentes utilizando somente código Ruby. Esse é o tipo de ousadia que assusta. Eu me assustei quando vi pela primeira vez o React colocar HTML, JS e CSS (StyledComponents) dentro de um componente. Eu me assustei ao ver o Tailwind criar classes para cada propriedade do CSS e termos HTML criados com dezenas de classes em um elemento. Abrir mão desse "preconceito" e testar o Phlex foi importante aqui. Mas o fator decisivo foi acompanhar o criador do Phlex, o [Joel Drapper](https://x.com/joeldrapper), nas redes sociais e perceber o quão motivado ele está.

## Biblioteca de componentes

Como não gostamos de reinventar a roda aqui na Linkana, resolvemos buscar bibliotecas de componentes que pudéssemos usar e chegamos a avaliar:

- https://phlexui.com/
- https://primer.style/guides/rails
- https://shadcn.rails-components.com/
- https://railsdesigner.com/
- https://zestui.com/
- https://railsui.com/
- https://protos.inhouse.work/

Acabamos escolhendo a [Phlex UI](https://phlexui.com/) não por acreditar que ela está pronta, mas por acreditar que o caminho que ela escolheu é o mais adequado à premissa de componentes reutilizáveis e de fácil customização. Ela é uma biblioteca que foi claramente inspirada na Shadcn e trouxe para o mundo Rails algumas inovações do Shadcn.

1. Incentivar que você [customize](https://phlexui.com/docs/customizing_components) os componentes copiando-os para a sua codebase.

2. Uma estrutura de componentes muito parecida com o React:

Shadcn
```javascript
Accordion type="single" collapsible className="w-full">
  <AccordionItem value="item-1">
    <AccordionTrigger>Is it accessible?</AccordionTrigger>
    <AccordionContent>
      Yes. It adheres to the WAI-ARIA design pattern.
    </AccordionContent>
  </AccordionItem>
</Accordion>
```

PhlexUI
```ruby
render PhlexUI::Accordion.new do
  render PhlexUI::Accordion::Item.new do
    render PhlexUI::Accordion::Trigger.new do
      p{ "What is PhlexUI?" }
    end
      
    render PhlexUI::Accordion::Content.new do
      p { "PhlexUI is a UI component library for Ruby devs who want to build better, faster." }
    end
  end
end
```

3. Todo o CSS é escrito com Tailwind dentro do próprio componente. É muito fácil fazer pequenos ajustes/mudanças.

4. Os componentes são formados por várias classes Ruby muito simples. É um código muito fácil de entender.

![Componentes Phlex UI](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kzn0y1wap4fq21dnl438.png)

5. Integração com Stimulus através de controllers específicos de cada componente.


## Colocando em produção - SSR + SPA

O primeiro passo para começar a migração para SSR com Phlex e Hotwire foi mapear os componentes do PhlexUI e colocá-los no [Lookbook](https://lookbook.build/) dentro da nossa aplicação com as cores da nossa marca.

![Lookbook](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hmnmmo5gbazzc3nvya30.png)

O segundo passo foi criar uma versão em Rails de todos os elementos de navegação. Sidebar, tabs, etc.

Dessa forma, conseguimos ir reescrevendo rota por rota usando SSR ao mesmo tempo que as rotas em React (SPA) continuam funcionando. Por exemplo:

![dashboard](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kmwybxgx8bse27myzfp4.png)

Tudo que faz parte do Dashboard já está utilizando SSR. Navegar entre as abas "Resumo" e "Lead time" é uma navegação que utiliza o Turbo do Hotwire.

![Pendências](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/krc5by32evcpda0v6jpt.png)

Quando o usuário clica na aba de pendências, desabilitamos o Turbo e é feita uma requisição de HTML ao backend que carrega nossa SPA em React e a página é exibida. Com isso, a aplicação muda para o modo SPA e as requisições voltam a ser via nossa API GraphQL com troca de JSON.

Se o usuário clicar num link que já está em Hotwire, fazemos com que o React realize uma requisição de HTML e a aplicação volte a ser uma SSR.

A transição do SPA para o SSR é praticamente imperceptível, mas do SSR para o SPA é um pouco mais demorada, sem atrapalhar a experiência do usuário. Nossa ideia é finalizar essa transição até a próxima edição do [Tropical.rb](https://www.tropicalrb.com/).

Desde o dia 11 de junho, estamos rodando o Phlex em produção e, como forma de agradecimento, a Linkana passou a ser um dos [sponsors do projeto](https://github.com/sponsors/joeldrapper#sponsors). Também já começamos a contribuir com o projeto do PhlexUI.

Se você também está trabalhando com componentes em Rails, deixe nos comentários o que você tem feito.