Refatoração de código React
Tags: javascript, refactoring, react, braziliandevs
Published: 2020-02-06 17:51:31

Trago neste artigo alguns aprendizados acumulados durante minha carreira. É importante lembrar que apesar dos exemplos serem um pouco generalizados são voltados para utilização dentro de aplicações que utilizem componentes em React e que por isso supõe-se que u leitore tenha algum conhecimento sobre a biblioteca e também sobre ECMAScript.

Também adiciono que podem ter pontos tanto básicos da linguagem quanto algo avançado.

<small>E meu português para artigos continua coloquial e com alguns erros de sintaxe que possam gerar confusão.</small>

---

Esse é um assunto recorrente para toda pessoa programadora e em qualquer outra linguagem e em qualquer era da computação.

## Contos da meia noite

(em _fast forward_)

Para contar uma história resumida ao extremo sobre como surgiram padrões de projeto, ~~[Our whole universe was in a hot, dense state](https://youtu.be/CMSYv_Z4SI8)...~~ dois programadores: [Kent Beck](https://en.wikipedia.org/wiki/Kent_Beck) e [Ward Cunningham](https://en.wikipedia.org/wiki/Ward_Cunningham) pegaram as idéias de um arquiteto chamado [Christopher Alexander](https://pt.wikipedia.org/wiki/Christopher_Alexander) e tentaram portá-las para o mundo da criação de Software.

> fonte: [Wikipedia](https://en.wikipedia.org/wiki/Software_design_pattern)

Depois vieram os [Gang of Four](https://en.wikipedia.org/wiki/Design_Patterns), 4 outros autores, e lançaram um livro:

![Capa do livro Design Patterns](https://upload.wikimedia.org/wikipedia/en/7/78/Design_Patterns_cover.jpg)

Trata-se de um compilado de **padrões de projeto** para programação orientada a objetos e que foi base para toda a popularização sobre o tema, tal que foi portado e adaptado para todas as outras linguagens.

E este é só um _storytelling_ para dizer que este problema pode ser mais antigo o quanto você imagina e que a dor está em todos os lugares.

## Tá, mas e o React?

Falando da **lib** em si, a própria documentação tem uma parte [falando sobre o tema](https://pt-br.reactjs.org/docs/design-principles.html), explicando como foi tracejado sua concepção. Recomendo a leitura para entender mais como foram as idéias por trás de sua criação.

Tendo em mente tais idéias, antes de apresentar a minha lista gostaria de evidenciar alguns ideais de desenvolvimentos que serão pertinentes para o decorrer deste artigo:

- [**DRY** - Don't Repeat Yourself](https://pt.wikipedia.org/wiki/Don%27t_repeat_yourself)
- [**KISS** - Keep it simple...](https://pt.wikipedia.org/wiki/Princ%C3%ADpio_KISS)
- Formatação Vertical & Horizontal - [Clean Code](https://books.google.com/books/about/?id=GXWkDwAAQBAJ&printsec=frontcover&source=kp_read_button&redir_esc=y#v=onepage&q&f=false)

Se não tiver com pressa, busque sobre o assunto no Google mesmo, depois volte aqui :D

### Bom senso

Creio que acima de tudo, vale o bom senso. Talvez da própria pessoa desenvolvedora (ou seja, você) ou mesmo em acordo de time. O padrão de desenvolvimento adotado na concepção do produto deve ser um princípio na criação do produto. Um ótimo exemplo é no link lá em cima dos [princípios de design do React](https://pt-br.reactjs.org/docs/design-principles.html), o importante é o projeto ter consistência.

Não fará nenhum sentido colocar 20 _design patterns_ enquanto você cita 10 nomes de pessoas importantes no desenvolvimento de Software se ninguém mais do seu time comprar a idéia. Seu código não tornará mais legível se quem ler seu código não entender onde você quer chegar.

## Minha listinha

Essa lista não é bem uma lista, mas sim algumas releituras de documentações e alguns exemplos de melhorias de código que fui acumulando durante minha carreira.

Também aponto uma outra fonte de padrões já existentes: https://reactpatterns.com/

Citarei alguns padrões existentes na lista deles porém com outro viés.

Também gostaria de explicar algumas idéias básicas para quem é iniciante e que estão acessando esse artigo, então se algum item você achar básico demais pode pular.

### JS(X)?

> (_jeiésséquis_ is too _sexy_)

O [JSX](https://pt-br.reactjs.org/docs/introducing-jsx.html) é uma **extensão de sintaxe JavaScript** inspirada no **XML**, famoso "tag HTML dentro do seu JS". Coloco ele como uma primeira idéia a discutir pois ainda vejo muita galera que está começando com React achá-lo estranho. E é mesmo.

Porém gostaria de dismistificá-lo. O **JSX**, tal como explicado na documentação do React, diz-se "uma extensão de sintaxe para JavaScript". E realmente é. Apesar de popularizado pelo React, tem muito mais a ver com o **Babel**, que é uma ferramenta que compila seu código **ECMAScript** para uma versão que pode ser interpretada pelos navegadores.

> **ECMAScript** é a mesma coisa que **JavaScript**, só que [sem direitos autorais](https://www.theregister.co.uk/2018/04/18/oracle_ios_app_takedown_javascript/)

Ou seja, quando você ver esse código:

```js
function Component ({ children, ...props }) {
  return <div {...props}>{children}</div>
}
```

Se trata apenas de **ECMAScript**.

```js
function Component ({ children, ...props }) {
  return React.createElement('div', props, children)
}
```

Se não acredita em mim, [teste você mesmo!](https://babeljs.io/repl#?browsers=&build=&builtIns=false&spec=false&loose=false&code_lz=GYVwdgxgLglg9mABAeSgCwKYCcDCcC2ADghmFIgBQDeiEaMANgCZamIC-AlIlQFCKJWUEFiQAeJjABuPAHTzCWOIQDO7AHxU6jFqXZiA9JKnre7Xr1CRYCRHiIkylGtuaswAGkTzZi5So5uPgEhEXFUTFwCYjBSciofP1UNLXo3PUMI7HsYuNN2IA&debug=false&forceAllTransforms=false&shippedProposals=false&circleciRepo=&evaluate=false&fileSize=false&timeTravel=false&sourceType=module&lineWrap=true&presets=es2017%2Creact%2Cstage-2&prettier=false&targets=&version=7.8.3&externalPlugins=) Escrevendo sem **JSX** você consegue usar **React** direto no navegador, já que o mesmo não entende código **JSX**.

> "Ah mas eu uso **classes**".

Classes no **ES6** são apenas [syntax sugar](https://medium.com/@naveenkarippai/debunking-fake-classes-in-javascript-78f67a6b5c96) de funções e prototipagem. Brinque um pouco com o [REPL do Babel](https://babeljs.io/repl) e veja como seria seu código para navegadores que não suportam ES6.

Darei outro exemplo abaixo, utilizando um componente dentro de outro:

```js
function OutroComponente ({ children, ...props }) {
  return <div {...props}>{children}</div>
}

function Component ({ children, ...props }) {
  return <OutroComponente {...props}>{children}</OutroComponente>
}
```

O **Babel** transforma o acima no abaixo.

```js
function OutroComponente ({ children, ...props }) {
  return React.createElement("div", props, children);
}

function Component ({ children, ...props }) {
  return React.createElement(OutroComponente, props, children);
}
```

**No final é tudo função.** - Guarde bem essa afirmação.

### Render _wat_

![meme de uma mulher com uma legenda escrita "wat"](https://i.ytimg.com/vi/lxZTcDePoqI/maxresdefault.jpg)

No React meu componente pode retornar um componente ou uma composição de componentes.

```js
function Component () {
  return <OtroComponente />
}
```

Mas lembre também que seu componente pode retornar também outros tipos:

#### Strings

```js
function Component () {
  return "Oi leitore!"
}
```

#### Null

```js
function NullComponent () {
  return null
}
```

(na verdade ele não renderiza nada visual)

#### Array

```js
function ArrayComponent () {
  return [
    'Repetindo ',
    9,
    <NullComponent key='null' />,
    <StringComponent key='string' />
  ]
}

// Renderiza: "Repetindo 9Oi leitor!"
```

> (Após o React v16.2)

É importante ressaltar que é necessário o atributo `key` e que assim funciona da mesma forma que a maioria dos _reacteires_ estão acostumados a enfrentar laços de repetição:

```js
function Component ({ items }) {
  return (
    <div>
      {
        items.map(({id, value}) =>
          <span key={`item-{id}`}>{value}</span>)
      }
    </div>
  )
}
```

<small>**edit:** por favor, não utilize o índice do _array_ como atributo `key`. Obrigado **Stefano** por me lembrar.</small>

Seria como imprimir um vetor de componentes:

```js
function Component (...) {
  return (
    <div>
      {[
        <span key={`item-1`}>{item1}</span>,
        <span key={`item-2`}>{item2}</span>,
        <span key={`item-3`}>{item3}</span>,
        {/* ... */}
      ]}
    </div>
  )
}
```

<small>**edit 2:** A forma como o Typescript lida com _childrens_ pode ser diferente.</small>

#### [Fragments](https://reactjs.org/blog/2017/11/28/react-v16.2.0-fragment-support.html)

Também na versão do React v16.2 vieram os fragmentos. A idéia é bem similar aos [DocumentFragment](https://developer.mozilla.org/pt-BR/docs/Web/API/DocumentFragment) já existente no **DOM**.

```js
function Component () {
  return (
    <React.Fragment>
      <li>hum</li>
      <li>dovs</li>
      <li>trevs</li>
    </React.Fragment>
  )
}
```

Utilizando o **Babel** após a **versão 7** também é possível utilizar um _shorthand_:

```js
function Component () {
  return (
    <>
      <li>hum</li>
      <li>dovs</li>
      <li>trevs</li>
    </>
  )
}
```

Link do [repl do Babel](https://babeljs.io/repl#?browsers=&build=&builtIns=false&spec=false&loose=false&code_lz=GYVwdgxgLglg9mABAYTgWwA4IKZiogCgEpEBvAKEUQCdsoRqkDKrEAeAPhdfYBsYOACxBo2Aen5ceVNpIAmcAG4BncZO6tZAqLRVqBG8VMRFyAXyA&debug=false&forceAllTransforms=false&shippedProposals=false&circleciRepo=&evaluate=false&fileSize=false&timeTravel=false&sourceType=module&lineWrap=true&presets=react%2Cstage-2&prettier=false&targets=&version=7.8.3&externalPlugins=) pra você brincar.

### Declaração de função: explícita ou _Arrow Function_

> Nota da autora: essa é uma posição pessoal. Fique livre em discordar e não utilizar.

Para componentes React **minha preferência** é para funções explícitas quando não utilizar <abbr title="High Order Components">**HOC**</abbr> ou algum "gerador" de componente. Um exemplo claro de função retornando componentes são `styled components`:

```js
const Button = styled.button`
  /* ... */
`
```

#### Mas ...Por que?

Prefiro funções explícitas pois, por legibilidade, é mais fácil encontrar uma função no meio de diversas outras quando está declarada explicitamente que uma no meio de diversas `const`s.

Também historicamente o React DevTools não pegava o nome do componente a não ser que estivesse sido declarado utilizando função explícita. Hoje a história é outra. O DevTools consegue (nem sempre, discutirei mais a frente) pegar o nome do componente sem problemas.

<!-- @TODO displayName -->

_Arrow Functions_ são anônimas, o que dependendo do problema chega-se a outro padrão:

### [.displayName](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/display-name.md)

Use quando necessário. Fica difícil depurar código quando o **DevTools** mostra toda uma árvore de _`Anonymous` Components_. Não é nem questão de escrever ou não utilizando _arrow function_, adicionar `.displayName` não mata gatinhos e vai auxiliar bastante mesmo para diminuir a quantidade de `styled(AlgumaCoisa)` que pode prejudicar a visualização.

[E vai aparecer bonito na _stacktrace_](https://github.com/facebook/react/blob/90294ead4c627715cb70f20ff448bb0d34ee4c1b/src/renderers/shared/stack/reconciler/ReactCompositeComponent.js#L50-L52)

### Smart vs Dumb Components

> **(no geral)** _Dumb Components_ são fáceis de _mockar_, testar e inclusive de visualizar no Storybook

Separe sempre que possível seus componentes. Curto e utilizo bastante o [Storybook](https://storybook.js.org/). Com ele é possível deixar um componente _fullscreen_ e inclusive utilizar uma _view_ inteira da sua aplicação, _mockando_ seus dados caso ela seja _burra_ e testar a responsividade da página inteira utilizando o **Chrome DevTools**.

### [.defaultProps](https://pt-br.reactjs.org/docs/typechecking-with-proptypes.html#default-prop-values)

Há duas formas para atribuir valores padrão para as `props` em Componentes Funcionais:

```js
function Greeting({ name = 'Kitsu' }) {
  return <div>Hi {name}!</div>
}
```

e

```js
function Greeting({ name }) {
  return <div>Hi {name}!</div>
}

Greeting.defaultProps = {
  name: 'Kitsu'
}
```

Prefira o primeiro formato exceto no caso que descreverei abaixo:

### [shouldComponentUpdate()](https://pt-br.reactjs.org/docs/optimizing-performance.html#shouldcomponentupdate-in-action)

Quando fazíamos componentes usando classes, havia uma forma de otimizar a renderização e deixar explícito para o React quando é para renderizar novamente ou não dependendo de alguns fatores previamente configurados. Esta ferramenta é o `shouldComponentUpdate`.

```js
class MyComponent extends Component {
  shouldComponentUpdate(nextProps, nextState) {
    // props
    if (this.props.name !== nextProps.name) {
      return false
    }

    // state
    if (this.state.name !== nextState.name) {
      return false
    }
  }

  render () {
    // ...
  }
}
```

Em componentes criados a partir de classes é possível utilizá-lo para controlar a renderização somente quando há alteração de `props` ou do `state` e inclusive dizer quais mudanças o componente deveria ativamente ouvir para renderizar ou não o componente.

Ainda sobre componentes de classes, também existe um `shorthand` que faz uma checagem `shallow` (raza):

```js
class MyComponent extends PureComponent {
  render () {
    // ...
  }
}
```

A comparação raza é feita da seguinte forma: ele verifica se algum ítem de `props` ou do `state` alteraram no primeiro nível dos objetos. Trabalhando com **imutabilidade** dá pra gerenciar bem quando o componente deve renderizar.

#### E pra Componentes Funcionais?

O [React.memo](https://pt-br.reactjs.org/docs/react-api.html#reactmemo) é algo novo (veio na versão `16.6`) e veio exatamente para auxiliar neste problema, só tem um detalhe: funciona apenas para `props` (pois estados utilizando **Hooks** são executados dentro do próprio _render_ do componente, não sendo possível uma interceptação do dado pelo _React.memo_). Abaixo um exemplo retirado da documentação.

```js
function MyComponent(props) {
  /* renderize usando props */
}

function areEqual(prevProps, nextProps) {
  /*
  se prevProps e nextProps renderizam o mesmo resultado,
  retorne true.
  caso contrário, retorne false.
  */
}

export default React.memo(MyComponent, areEqual);
```

A maneira que o React lida com estado de componentes funcionais foi introduzida na versão 16.8 com a vinda dos `Hooks`.

Como os _Hooks_ são executados dentro da própria função de _render_, o `React.memo` não consegue manusear por fora do componente o que acontece dentro dele.

E aí que vem o ganho de utilizar `.defaultProps` fora dos argumentos do React:

```js
function Greeting({ name }) {
  return <div>Hi {name}!</div>
}

Greeting.defaultProps = {
  name: 'Kitsu'
}

const MemoGreeting = React.memo(Greeting)
```

Você pode deixar ítens no `.defaultProps` e eles ficam disponíveis para comparação na função do `React.memo`. Quando você deixa _default props_ dentro da chamada dos argumentos da função, ele sempre será executado somente após o _React.memo_, não sendo possível efetuar a comparação.

### _Prop Types_ com _Spread_ de atributos

<small>(Se você usa **TypeScript** ~~(ou **Flow**)~~, pule uma casa.)</small>

No **React Patterns** tem um exemplo bem bacana, mas gostaria muito de compartilhar um fato quando define-se `propTypes` no JavaScript. Pense no exemplo a seguir:

```js
function Greeting({ name, ...restProps }) {
  return <MyDiv {...restProps}>Hi {name}!</MyDiv>;
}

Greeting.propTypes = {
  name: PropTypes.string.isRequired
}
```

O mais comum é deixar que o componente `MyDiv` tenha sua validação de _Prop Types_. Porém se em algum momento você precisar validar no seu componente coisas que já são validadas nos _Prop Types_ do componente filhe, lembre que o `.propTypes` é um objeto.

```js
Greeting.propTypes = {
  ...MyDiv.propTypes,
  name: PropTypes.string.isRequired
}
```

Você pode estender os seus _Prop Types_ com qualquer outro objeto de _Prop Types_.

### Condicionais

Ter condicionais no meio do `JSX` é um _anti-pattern_ bem eficaz, muito utilizado e amplamente difundido por _reacters_. É normal encontrar um _short-circuit evaluation_ ou mesmo um ternariozinho aqui ou lá e retirar esses condicionais torna o código verboso por provavelmente precisar criar mais Componentes. Porém creio que todos que já codaram React também já viram códigos com uma superutilização delas.

```js
function Component ({ vaiChover, diaDeBanho, calor }) {
  return (
    <div>
      {!vaiChover && diaDeBanho && calor && <Chuveiro />}
    </div>
  )
}
```

Nestes casos o que recomendo como ação básica imediata é: extraia a lógica de condicionais para uma variável a parte:

```js
function Component ({ vaiChover, diaDeBanho, calor }) {
  const shouldDisplayChuveiro = !vaiChover && diaDeBanho && calor
  return (
    <>
      {/* ... */}
      {shouldDisplayChuveiro && <Chuveiro />}
      {/* ... */}
    </>
  )
}
```

Melhora a legibilidade? Nem tanto.

Porém em alguns casos é possível jogar essa responsabilidade pro componente filho (claro, quando fizer sentido essa responsabilidade ser repassada para ele). Lembra que você pode fazer seu componente retornar [null](#null) e não renderizar conteúdo?

```js
function Chuveiro ({ vaiChover, diaDeBanho, calor }) {
  if (vaiChover) return null
  if (!diaDeBanho) return null
  if (!calor) return null

  return 🚿
}

function Component (props) {
  return (
    <>
      {/* ... */}
      <Chuveiro {...props} />
      {/* ... */}
    </>
  )
}
```

### [Proxy](https://reactpatterns.com/#proxy-component)

O site do React Patterns tem um ótimo exemplo simples com um botão:

```js
<button type="button">

// Ergo Proxy
const Button = props =>
  <button type="button" {...props} />
```

Mas gostaria de estender essa idéia. Na verdade, tá mais para um _hack_. No React você _grosseiramente_ pode utilizar componentes com ponto (`.`). Um exemplo da própria documentação do React é a [Context API](https://pt-br.reactjs.org/docs/context.html#reactcreatecontext).

```js
const MyContext = React.createContext(defaultValue)

// Provider
<MyContext.Provider value={/* some value */}>

// Consumer
<MyContext.Consumer>
  {value => /* renderiza algo baseado no valor do context */}
</MyContext.Consumer>
```

Ok, eu menti sobre usar componentes contendo ponto no nome, tecnicamente não é o correto. Mas sim, você pode utilizar componentes como atributos de objetos. Isso possibilita a criação de certos componentes "escopando" sua utilização, como por exemplo:

```js
import MyBanner from 'path/to/MyBanner'

<MyBanner>
  <MyBanner.CloseButton>Mensagem a11y pro botão de fechar</MyBanner.CloseButton>
  <MyBanner.Image
    src="https://..."
    alt="mensagem descritiva sobre a imagem" />
  <MyBanner.Text>Conteúdo pro meu banner</MyBanner.Text>
  <MyBanner.Cta onClick={handleOnClick}>E aqui vem o call-to-action</MyBanner.Cta>
</MyBanner>
```

E o arquivo do meu componente seria algo como:

```js
// MyBanner.js

const MyBanner = styled.div`...`

MyBanner.CloseButton = styled.button`...`
MyBanner.Image = styled.img`...`
MyBanner.Text = styled.p`...`
MyBanner.Cta = styled.button`...`

export default MyBanner
```

Claro que esse padrão é longe de ser algo ideal, eu diria que é muito mais situacional: quando não há um controle sobre criação de componentes que sejam reutilizáveis ou para algo muito específico que vale ter tal escopo.

Ainda ressalto que o ideal e mais recomendável seria utilizar componentes já existentes:

```js
import MyBanner from 'path/to/MyBanner'

<MyBanner>
  <CloseButton>Mensagem a11y pro botão de fechar</CloseButton>
  <Image
    src="https://..."
    alt="mensagem descritiva sobre a imagem" />
  <Text>Conteúdo pro meu banner</Text>
  <Button onClick={handleOnClick}>E aqui o call-to-action</Button>
</MyBanner>
```

## E Hooks?

Creio que este é um assunto que vale uma nova postagem só para este assunto e acho que já me estendi em vários outros aspectos.

Mas tudo que falo para componentes vale para funções ;D

## Quando refatorar?

Queria usar etimologia para lembrar que sempre dizemos **refatorar** e nunca **fatorar**. Ou seja, antes de tudo: faça funcionar. E exatamente por fazer funcionar, ninguém vai fazer um código [a la John Carmack](https://kotaku.com/the-exceptional-beauty-of-doom-3s-source-code-5975610?post=56177550) de primeira. Também muitos de nós enfrentamos entregas, não há como fugir.

Faça com calma e coloque testes. Lembre daquele ciclo do **TDD** e aplique: **red-green-refactor**. Faça o teste para quebrar; faça funcionar e então faça direito. Ou mesmo:

> [Faça funcionar, faça direito, faça-o executar rapidamente](https://wiki.c2.com/?MakeItWorkMakeItRightMakeItFast). - Kent Beck

## Por que refatorar?

Mesmo com a correria de prazos, refatorar o código de uma maneira que utilize padrões já conhecidos ou mesmo sem utilizá-los já é um ganho quando bem executado. Se o produto tem a necessidade de ter futuras manutenções e ser escalável, é necessário ter um código de fácil legibilidade e sem muito atrito para modificações e melhorias.

Ainda jogo uma analogia com algo da nossa área: para otimizar a rapidez de leitura geralmente bancos de dados gastam mais tempo na parte da escrita para deixá-lo com certa ordenação para facilitar no resgate do dado.

Creio que para código podemos ter algo semelhante: perca um tempo para escrever um código que fique fácil de dar manutenção pois quando for preciso e chegar a hora da manutenção, terá menos problemas e vai ser mais rápido fazer qualquer alteração.

## Como refatorar?

Eu indico [Refactoring, do Martin Fowler](https://martinfowler.com/books/refactoring.html) ~~e também o [Clean Code, do Uncle Bob](https://books.google.com.br/books/about/C%C3%B3digo_Limpo.html?id=GXWkDwAAQBAJ&printsec=frontcover&source=kp_read_button&redir_esc=y#v=onepage&q&f=false)~~.

Os pontos abaixo são bem explorados pelos livros e creio que com estas 2 dicas sensacionalistas resumidas você irá conseguir escrever seu código tão desejado:

### Formatação

Atente-se à formatação do teu código. No **Clean Code** há partes onde explicam tanto **formatação horizontal** quanto **formatação vertical**.

Em qualquer idioma, ler parágrafos grandes prejudica a leitura de qualquer conteúdo editorial. Da mesma forma, ter código pouco espaçado ou com muito _scroll_ acaba virando um pesadelo para entender seu funcionamento.

### Escreva seu código como uma carta de amor para outro desenvolvedor

Levem na brincadeira a afirmação porém escrevam código para que outros desenvolvedores entendam, você inclusive. E não estou dizendo de encher seu código de comentários que muitas vezes podem ser redundantes. Deixe o **seu** código semântico, não importando se é HTML, JS ou qualquer outra linguagem, e que seja fácil de ser lido e com APIs de fácil utilização. Faça com que seu componente seja fácil de ser utilizado e entendido. Faça uma boa documentação e de fácil manutenção/atualização (ex: _Storybook_) e automatize o que for possível (ex: documentar as _PropTypes_ direto da declaração de interface do _TypeScript_).

Algo que vejo crescer nos últimos anos é o termo [Developer Experience (DX)](https://hackernoon.com/the-best-practices-for-a-great-developer-experience-dx-9036834382b0). Mesmo se seu código não for aberto, ao escrever código que possa ser lido [até por uma criança de 5 anos](https://www.reddit.com/r/EILI5/) (não literalmente, pfv), isso pode facilitar pra você mesmo quando tiver de dar manutenção 5 anos depois, lembrando _zero_ em relação ao conhecimento que você possui no momento da escrita do código.

## Estrutura

Para estruturar arquivos e código existem diversos padrões. Antes de tudo: dê preferência pro padrão já existente, ainda mais se for um padrão já adotado pelo time.

Existem diversos padrões: [ducks](https://github.com/erikras/ducks-modular-redux), [Clean Architecture](https://www.freecodecamp.org/news/how-to-write-robust-apps-consistently-with-the-clean-architecture-9bdca93e17b/)...

Pessoalmente gosto de algo mais livre com uma pegada mais funcional e um pouco de <abbr title="Domain Driven Design">DDD</abbr>. Caso também seja o teu perfil, recomendo bastante a estrutura do **Dan Abramov**:

> https://react-file-structure.surge.sh/

E eu estenderia também para código, tal como [John Carmack](http://number-none.com/blow/john_carmack_on_inlined_code.html) sugere. Como citado anteriormente: Se teu módulo (arquivos <abbr title="ECMAScript Modules">**ESM**</abbr>) começar a ficar grande, quebre em mais arquivos.

### Estrutura **bonus**

Tente também não criar uma estrutura de arquivos muito aninhada. Tente sempre deixar o mais _flat_ possível, ou seja, evite diretórios dentro de diretórios virar uma árvore gigante. Tente sempre deixar o mais perto possível da raiz do pacote/projeto e quebre mais os seus componentes e código se começar a aninhar muito.

Se seu projeto for um **monorepo**, extraia/quebre funcionalidades em módulos/pacotes. ["Make each program do one thing well"](https://en.wikipedia.org/wiki/Unix_philosophy). Quebre mais seu código e faça com que seus módulos sejam pequenos e que façam apenas uma coisa e bem. Isso também facilitará na hora de trocar um **módulo** por outro e facilita também na hora de criar testes.

## E não se esqueça

![Comercial da Caloi antiga que dizia "Não se esqueça da minha Caloi"](https://images.uncyc.org/pt/thumb/d/db/Caloi.jpg/300px-Caloi.jpg)

Use tanto testes quanto estilo de código (_Coding Style_) e ferramentas de automatização ao seu favor. Faça interfaces que facilitem o uso de componentes, _"Não me faça pensar"_.

![Capa do livro "Não me faça pensar"](https://d1pkzhm5uq4mnt.cloudfront.net/imagens/capas/mp_64a646094d7cf506020b3c25608a1cda.jpg)

Quanto mais abstraído teu código e fácil de entender, mais rápido será para fazer alterações, dar manutenção e adicionar funcionalidades.

## Conclusão

Desenvolvimento de Software ainda é uma disciplina bem artesanal. Mesmo tendo automações, ainda é necessário escrever código para que programas, _sites_ e aplicativos funcionem. Ainda não é acessível ter automatizado algo que nos _cuspa_ códigos, pior ainda para _frontend_ que ainda temos que além de pensar em fazer um bom código e tanto seu código quanto a saída pro usuário devem ser semânticas, leves e rápidas para rodar em celulares e em leitores de tela por exemplo.

Outra profissão que gosto de citar é a de arquitete, já que as idéias para padrões de projetos foram inspiradas por um. Só que a diferença é que nós pessoas desenvolvedoras temos que arquitetar sistemas que além de possuir uma base boa e forte, todo o produto deve ser escalável e possível de adicionar novas funcionalidades, algo que para um arquitete seria bem mais limitado.

Enquanto a tecnologia não evoluir a ponto de escrever programas inteiros usando inteligência artificial e automações, apesar de escrevermos códigos que serão lidos pela máquina, não se esqueça que eles também serão lidos por outros humanos.

## EDIT

Por favor, se for consumir os livros: "Código Limpo", "Arquitetura Limpa" ou "Codificador limpo" não compre, ~~pirateie~~.

Pois o autor é assumidamente **transfóbico**. Sei que é um pedido egoísta mas por favor, não consuma artigos de pessoas transfóbicas.