Organizando uma aplicação com React
Published: 2020-10-31 19:15:13

A cada dia que passa surgem uma nova library ou framework no mundo JavaScript.

Com isso surgem diversas dúvidas: como arquitetar aplicações com React de forma escalável, fácil e de um jeito que seja possível fazer alterações sem quebrar o projeto?

Nesse post vou mostrar uma dessas formas, falando sobre:

#Componentização
#Organização dos arquivos
#CSS Modules

Componentização e vantagens
A vantagem principal do React, e da componentização como um todo, é manter num mesmo arquivo, ou pelo menos com uma certa proximidade, os módulos (ou lógicas) que se comunicam.

Nos tempos do jQuery, tínhamos o oposto disso:

arquivo index.html
<div>
  <button id="button">Click me</button>
</div>

arquivo main.js
$("#button").bind("click", function() {
  alert("Clicked");
});

arquivo style.css
#button {
  background-color: blue;
  border: none;
  color: white;
  padding: 5px 10px;
}

Três arquivos separados e distantes, que interagiam entre si.
Conforme a aplicação cresce, a dificuldade de manutenção sobe exponencialmente com essa abordagem.

Já no mundo React, com a componentização, temos isso:

import React from 'react';

const styles = {
  backgroundColor: 'blue',
  border: 'none',
  color: white,
  padding: '5px 10px'
};

const Main = () => (
  <button
    onClick={() => alert('Clicked')}
    style={styles}
 >Click me</button>
);

export default Main;

Em apenas um arquivo, toda lógica referente ao botão que é clicado, inclusive seu layout, estão reunidos.

As vantagens?

Se precisarmos deletar essa feature, deletaremos tudo de uma vez de forma fácil sem deixar código legado.
Bugs são mais fáceis de rastrear e consertar, porque tudo que pode afetar o componente está reunida em apenas um lugar.
Podemos editar o componente de forma muito mais rápida.
É importante o entendimento desse argumento, de deixar as lógicas que interagem entre si no mesmo arquivo (ou bem próximas) porque toda a arquitetura que veremos nesse post será baseada nisso.

Organização dos arquivos
Escalabilidade em aplicações client-side se resume ao poder de múltiplos desenvolvedores conseguirem fazer alterações no código, com o mínimo de falhas possíveis.
Para maximizar a escalabilidade da aplicação, iremos usar uma abordagem de organização de pastas por features. Sendo que essas features vão ficar dentro da pasta components.

src/
  assets/
  components/
    home/
    login/
    sidebar/
  services/

Com isso, se um bug for reportado, devemos procurar a pasta da feature onde o mesmo está ocorrendo.
Vale lembrar que dentro da pasta assets, ficam as fontes e imagens. Já na pasta services ficam serviços comuns aos projeto, também pode ser chamado de utils ou shared.
Uma das partes mais interessantes dessa abordagem, é a organização das pastas internas das features:

components/
  home/
    Home.js
    Home.spec.js
    styles.css

O componente está na mesma pasta do seu teste automatizado e do seu estilo.
Lembrando do argumento que levantei anteriormente, se precisarmos deletar essa feature, deletaremos tudo de uma vez sem deixar código legado.
Além de deixar claro que se mudarmos algo no componente, deveremos observar também o arquivo de testes.
E se precisarmos alterar algo no layout do componente, deveremos apenas olhar o arquivo styles.css dentro da pasta e mais nenhum outro, porque o único arquivo de estilos que vai estar impactando o componente é esse.
Se você entende de CSS, sabe que os estilos são globais. Então como podemos fazer com que os estilos possam valer apenas para um componente, ou seja, tenham escopo local?
CSS Modules
Essa característica do CSS, de ter seletores globais, pode ter algumas vantagens mas em geral é bem danosa para a sua aplicação. Principalmente com o crescimento dela.
E é nesse ponto que o CSS Modules é extremamente útil.

A ideia é ter o escopo dos estilos locais, funcionando apenas para um determinado componente. Como se fossem módulos.
Por isso o nome: CSS Modules.
Para demonstrar como o CSS Modules funciona na prática vamos utilizar o exemplo anterior do botão:

arquivo: Main.js

import React from 'react';

import styles from './styles.css';

const Main = () => (
  <button
    onClick={() => alert('Clicked')}
    className={styles.button}
  >Click me</button>
);

export default Main;


E o arquivo styles.css com os estilos:

.button {
  background-color: blue;
  border: none;
  color: white;
  padding: 5px 10px;
}

Portanto temos duas principais vantagens:
Escrever CSS da forma que já estamos acostumados e com todo o seu poder.
Evitar a maior fraqueza do CSS: o escopo global.
Concluindo
Em resumo, temos uma aplicação em que os componentes e as partes que interagem com ele ou estão no mesmo arquivo ou estão próximos de serem encontrados. Além disso, temos um CSS com todas as suas vantagens mas sem ser global.