Clean Code no Frontend

Clean Code no Frontend

Vamos falar de Clean Code, que nada mais é do que um “código limpo”. Para muitos desenvolvedores ter um código limpo significa escrever a menor quantidade possível de linhas.

Mas isso não é inteiramente verdade. O verdadeiro valor do Clean Code está em escrever códigos que são facilmente compreendidos tanto em sua estrutura, quanto em suas funções, concisos e que não podem ser interpretados de várias maneiras.


Precisamos mesmo de Clean Code?

É claro que quando levamos para um cenário do dia a dia escrever um código limpo e de fácil compreensão pode levar mais tempo, mas no longo prazo, todo o time colherá muitos benefícios.

Implementar, manter e refatorar será um desafio se você estiver trabalhando com um código de difícil leitura ou confuso. Você e seu time precisarão gastar muito tempo para entender o que está acontecendo ali gerando um desperdício de esforço desnecessário.

Aprender Clean Code é o melhor hack de produtividade que qualquer desenvolvedor pode fazer!

Vamos conhecer um pouco mais?

Características gerais


Podemos considerar características do Clean Code vários aspectos de desenvolvimento, como por exemplo:

  • Clareza: O Clean Code é claro e fácil de entender. Usa nomes significativos para variáveis, funções e classes e evita comentários confusos ou desnecessários.
  • Simplicidade: é simples e direto. Evita complexidade desnecessária e mantém as coisas o mais simples possível.
  • Modularidade: é modular e organizado. Ele é dividido em pequenos módulos ou funções reutilizáveis que são fáceis de testar e manter.
  • Consistência: é consistente em sua formatação, nomenclatura e estilo de codificação. Isso facilita a leitura e a compreensão e reduz a probabilidade de erros.
  • Testabilidade: é projetado para ser fácil de testar. Ele separa preocupações e dependências e evita pedaço de código que tenham muita dependência entre si, o que é difícil de se testar.

Mas e o frontend?


Embora muitos dos princípios do Clean Code sejam aplicáveis em qualquer linguagem de programação, há algumas considerações específicas que podem ser úteis ao desenvolver aplicações frontend.

Abaixo vamos ver alguns casos de Clean Code que para o frontend são importantes:

Separação de responsabilidade (Single Responsibility Principle)

É importante que as diferentes responsabilidades do frontend sejam separadas e organizadas de forma clara e coesa.

Neste exemplo, o componente UserProfile tem uma única responsabilidade: exibir as informações do perfil do usuário e fornecer um botão de logout. O componente usa o nome, e-mail e avatarUrl como props e os usa para renderizar as informações de perfil do usuário.

A função handleLogout também é definida dentro do componente. Esta função lida com a lógica de logout do usuário quando o botão é clicado. Ao manter essa lógica dentro do componente, estamos seguindo o SRP (Single Responsibility Principle) e garantindo que cada componente tenha apenas uma responsabilidade.

Separar a lógica para exibir as informações do perfil do usuário e manipular a funcionalidade de logout em funções separadas, torna esse código mais modular e fácil de manter. Se precisarmos atualizar a lógica de logout, basta modificar a função handleLogout e podemos fazer isso sem afetar o restante da funcionalidade do componente. Da mesma forma, se precisarmos atualizar como as informações do perfil do usuário são exibidas, podemos modificar o código JSX sem afetar a funcionalidade de logout.

Nomenclatura

Classes, IDs, componentes, funções, devem ser nomeados de forma significativa e descritiva de modo que facilitem a compreensão do código. Nomes genéricos devem ser evitados.

Aqui nós estamos usando uma boa nomenclatura, utilizando nomes descritivos e significativos para nossas variáveis e funções. Em vez de usar nomes genéricos como name, estamos usando firstName e lastName para descrever mais especificamente o nome do usuário.

Da mesma forma, estamos usando avatarUrl para descrever a URL da imagem do avatar do usuário e estamos usando ${firstName} avatar de ${lastName} para atributo alt da imagem para descrever o que é a imagem.

Usar nomes descritivos torna o código mais legível e fácil de entender. Quando outros desenvolvedores (ou nós mesmos) depois um tempo lemos o código, podemos entender rapidamente o que cada variável ou função faz, sem perder tempo decifrando nomes.

Ao usar uma boa nomenclatura, também podemos reduzir a probabilidade de erros e melhorar a capacidade de manutenção do código. Se precisarmos fazer alterações no código no futuro, podemos entender facilmente o que cada parte do código faz e fazer as modificações necessárias.


Reutilização de código

Neste exemplo, estamos usando Clean Code para melhorar a reutilização de código. Temos o componente Button separado, o que nos dá a possibilidade de usá-lo em outras partes da aplicação, em vez de repetir o mesmo código várias vezes.

O componente Button recebe props para a função label e onClick e retorna um botão simples com essas propriedades. Isso nos permite criar facilmente botões em toda a nossa base de código, sem ter que repetir o mesmo código de botão várias vezes.

Também estamos reutilizando este componente Button dentro do componente UserProfile, onde definimos a função handleLogout. Usando o componente Button com um label de Logout e um onClick de handleLogout, podemos criar um logout dentro do nosso componente de perfil de usuário, sem ter que escrever o código do botão novamente.

Usando esses princípios para melhorar a reutilização de código, podemos reduzir a quantidade de código que precisamos escrever, melhorar a capacidade de manutenção de nosso código e reduzir a probabilidade de erros.

Testabilidade

Aqui estamos tornando o nosso componente UserProfile mais testável. O principal recurso deste exemplo é a propriedade onLogout.

Em vez de definir a função handleLogout para lidar diretamente com a lógica de logout, estamos usando a propriedade onLogout para permitir que o componente pai defina a lógica de logout. Também verificamos se a propriedade onLogout está definida antes de chamá-la, para evitar erros se a propriedade não estiver definida.

Isso nos permite testar facilmente o componente UserProfile, dessa forma podemos passar uma função simulada de onLogout durante o teste e garantir que ela seja chamada corretamente quando o botão Logout é clicado.

Aqui está um exemplo de teste usando a biblioteca Jest.js.

💡
Observação: Caso você queira saber um pouco mais sobre testes, já fizemos um artigo sobre esse assunto que você pode ler na íntegra aqui.

Manutenção

O código frontend de uma aplicação pode se tornar muito grande e complexo com o tempo. Esse é um dos motivos para usar as técnicas do Clean Code. Assim, teremos um código limpo, com fácil manutenção e será necessário pouco tempo para entender como todos os componentes funcionam juntos. Isso com certeza fará você economizar tempo e recursos a longo prazo.

Veja esse exemplo a seguir:

Aqui especificamente, estamos usando a desestruturação de objetos para simplificar o código e torná-lo mais fácil de ler e modificar.

Em vez de passar props individuais para o primeiro nome, sobrenome, e-mail e URL do avatar do usuário, estamos passando um único objeto user que contém todas essas informações. Isso torna o componente mais modular e fácil de modificar, pois podemos facilmente adicionar ou remover propriedades do objeto user sem ter que modificar o código do componente.

Ao usar o Clean Code para melhorar a capacidade de manutenção de nosso código como este, podemos facilitar a modificação e a manutenção de nosso código ao longo do tempo.


Performance

O Clean Code também pode melhorar o desempenho do frontend, reduzindo a quantidade de código desnecessário e otimizando o código necessário. Isso pode levar a um tempo de carregamento mais rápido e consequentemente uma melhor experiência ao usuário.

Estamos mostrando aqui como melhorar o desempenho do componente UserList. Usamos o hook useMemo para memorizar a lista de usuários que está classificada, o que ajuda a melhorar o desempenho reduzindo reprocessamentos desnecessários.

O hook useMemo recebe uma função que retorna um valor memorizado e um array de dependências. Se alguma das dependências mudar, o valor memorizado é recalculado. Se nenhuma das dependências mudar, o valor memorizado é retornado do cache.

Isso pode ser particularmente útil nos casos em que a base de usuários é grande ou a função de classificação é cara.

Como resultado dessa técnica de Clean Code utilizada, melhoramos o desempenho do código, e podemos garantir que a aplicação seja rápida e responsiva para os usuários.

Acessibilidade

O Clean Code também pode ajudar a melhorar a acessibilidade do frontend para usuários com deficiências. Um código bem estruturado facilita a implementação de recursos de acessibilidade e garante que estes funcionem corretamente.

Aqui estamos adicionando uma propriedade aria-label ao botão, que ajuda a melhorar a acessibilidade para usuários que dependem de tecnologias assistivas, como leitores de tela.

A propriedade aria-label vai fornecer uma alternativa de texto para o botão, que é lida por leitores de tela em vez do texto visível. Isso pode ser útil nos casos em que o texto visível do botão não é suficiente para transmitir a finalidade do botão a usuários com deficiências.

Adicionando essa propriedade ao componente Button, melhoramos a acessibilidade do nosso código e garantimos que ele possa ser usado pelo maior número possível de usuários.

Dicas com o Clean Code

Espero que até aqui você tenha conseguido entender o que é o Clean Code, como utiliza-lo e os seus benefícios. Agora, vou mostrar de forma mais sucinta 7 dicas práticas que são muito utilizadas em tarefas diárias dos desenvolvedores frontend, e que consideramos como Clean Code:

1) Renderização condicional apenas para uma condição

Para renderizar algo condicionalmente quando uma condição for true e não renderizar nada quando uma condição for false, não use um operador ternário. Em vez disso, use o operador &&.


2) Renderização condicional em qualquer uma das condições

Se você precisar renderizar condicionalmente algo quando uma condição for true e renderizar outra coisa quando a condição for false, use um operador ternário.


3) Props Booleanas

Uma propriedade truthy pode ser aplciada a um componente apenas com o nome da propriedade sem um valor como este: myTruthyProp. Escrever como myTruthyProp={true} é desnecessário. Veja o exemplo abaixo para entender melhor:


4) Props de string

Uma props no formato de string pode ser aplicada entre aspas duplas sem o uso de chaves ou backticks.


5) Funções manipuladoras de eventos

Se um manipulador de eventos aceita apenas um único argumento para o objeto Event, você pode apenas fornecer a função ao manipulador de eventos: onChange={handleChange} sem ter a necessidade de agrupar a função em uma função anônima: onChange={e => handleChange(e)}.

6) Passando Componentes como Props

Ao passar um componente como uma prop para outro componente, não precisamos envolver esse componente em uma função se o componente não aceitar nenhum props.


7) Adereços Indefinidos

Propriedades indefinidas são excluídas, então não se preocupe em fornecer um undefined fallback se estiver tudo bem para o prop ser undefined.

Esses são alguns dos princípios de Clean Code que podem ser aplicados tanto ao desenvolvimento de aplicações frontend, quanto de backend. E lembrando que aplicar esses princípios:

  • É importante, pelo menos tão importante quanto outros conceitos como desempenho e evitar bugs.
  • É fácil para qualquer desenvolvedor ler.
  • É fácil para qualquer desenvolvedor modificar.
  • Foi escrito por alguém que se importa.
  • Faz o que se espera. O código não engana você, sem surpresas.


Como resultado sempre teremos um código mais legível, fácil de evoluir, manter e testar, gerando um grande aumento de produtividade a longo prazo e consequentemente desenvolvedores mais felizes.

Espero que tenham gostado do artigo e que estejam animados para colocar tudo isso em prática!

Bora codar!

💡
As opiniões e comentários expressos neste artigo são de propriedade exclusiva de seu autor e não representam necessariamente o ponto de vista da Revelo.

A Revelo Content Network acolhe todas as raças, etnias, nacionalidades, credos, gêneros, orientações, pontos de vista e ideologias, desde que promovam diversidade, equidade, inclusão e crescimento na carreira dos profissionais de tecnologia.