Clean Code e boas práticas de programação aplicadas ao React JS
Clean Code e boas práticas de programação aplicadas ao React JS
Só quem abriu o código numa segunda-feira e não sabia por onde continuar porque não estava entendendo nada do que estava escrito, sabe o caos que um código bagunçado é. Muitas vezes, achamos que iremos perder tempo refatorando código, pensando em melhores nomes ou em formas melhores de estruturar nossas funções. Mas eu garanto que o tempo que você vai perder lá na frente, se deixar esse código um caos, é muito maior. Pensando nisso, aqui estão reunidas algumas dicas de Clean Code para melhorar o seu código.
Atualmente, no ReactJS, os componentes baseados em funções são mais utilizados. Portanto, vamos começar esse tutorial de Clean Code com elas.
Funções
De acordo com Robert C. Martin, a primeira regra das funções é que elas devem ser pequenas. E a segunda regra é que elas devem ser menores ainda.
Isso se aplica tanto às funções normais quanto aos componentes funcionais do React. Assim, quanto menor, melhor.
Cada função deve fazer apenas uma coisa, esse é o princípio da responsabilidade única, SRP (Single Responsability Principle). Entretanto, esse é um conceito que deixamos passar com muita frequência.
Então, vamos a um exemplo, observe a seguinte função:
const submitForm = (e: any) => {
e.preventDefault();
if (emailValidator(email)) {
if (passwordValidator(password)) {
createUser({ email, password, name })
.then((response) => {
if (response === 200) AlertSuccess('Usuário criado com sucesso');
setEmail('');
setPassword('');
setName('');
setRegistration(false);
})
.catch((error) => {
AlertError(error.reponse.data.message);
});
} else {
AlertError(
'Digite uma senha válida. É necessário pelo menos oito dígitos sendo pelo menos um número e uma letra.'
);
}
} else {
AlertError('Digite um email válido');
}
};
Observe que a função “submitForm” é responsável por validar o formulário, enviar o formulário e resetar os
valores dos inputs. Dessa forma, usando o princípio da responsabilidade única, conseguimos extrair 3 funções dela e tornamos o código bem mais legível:
const submitForm = (event: any) => {
event.preventDefault();
const data = { email, password, name };
if (formIsValid(data)) createUserHandler(data);
};
const formIsValid = (form: registrationFormData) => {
if (!emailValidator(form.email)) {
AlertError("Digite um email válido");
return false;
} else if (!passwordValidator(form.password)) {
AlertError(
"Digite uma senha válida. É necessário pelo menos oito dígitos sendo pelo menos um número e uma letra."
);
return false;
} else if (!name.trim().length) {
AlertError("Digite um Nome válido");
return false;
} else {
return true;
}
};
const createUserHandler = (data: registrationFormData) => {
createUser(data)
.then((status) => {
if (status === 200) {
AlertSuccess("Usuário criado com sucesso")
resetInputs();
}
})
.catch((error) => AlertError(error.reponse.data.message));
};
const resetInputs = () => {
setEmail("");
setPassword("");
setName("");
setRegistration(false);
};
Isso também se aplica aos componentes funcionais. Assim, se existe algum componente que se repete em mais de um lugar, crie um componente apenas para ele. Reutilização de código é essencial. Afinal, essa é uma das vantagens de se utilizar React.
Agora, observe outra coisa no último exemplo de código: a função ‘submitForm’ chama a função ‘formIsValid’, que -por sua vez- chama a função ‘createUserHandler’, que chama a função ‘resetInputs’ e elas estão escritas nessa mesma ordem. Entretanto, aguarde! Pode uma função chamar outra que não existe antes dela?
Atualmente, no Javascript, isso não é um problema. Além disso, lembre-se que pessoas lerão o seu código e o comportamento normal ao lermos algo é de cima para baixo. Portanto, essa prática evita que precisemos ficar voltando e procurando a função que foi chamada, possibilitando uma leitura contínua do código.
Nomes
A forma como nomeamos as coisas no nosso código podem fazer a diferença na hora de definir se temos um bom código. Dessa forma, o nome de algo em seu código deve dizer o que ele faz ou o motivo de estar lá.
Observe o código a seguir:
const submitForm = (event: any) => {
event.preventDefault();
const formData = { email, password, name };
if (formIsValid(formData)) createUserHandler(formData);
};
Lendo essa função, você consegue fazer um parágrafo com base nela: quando o formulário for submetido a função, vai prevenir o comportamento padrão do navegador de atualizar a página. Em seguida, vai reunir os dados do formulário em uma variável. Assim, se o formulário for válido, ele vai tentar criar um usuário.
Dicas de Clean Code para nomenclatura
É esse tipo de lógica que se espera com as nomeações.
Evite abreviações e letras soltas como “x”. Na hora de lermos o código, já é o bastante termos que nos preocupar em decifrar a lógica por trás dele. Assim, não precisamos parar para pensar no que aquele nome de variável ou função significa.
Além disso, outra coisa para ter bastante cuidado são nomes que passam uma informação errada. Observe o seguinte exemplo:
import { PageTitle } from './styles';
const LoginPage = () => {
return (
<>
<section>
<PageTitle>
<h2>The</h2>
<h2>Greatest</h2>
<h2>App</h2>
<p>for</p>
<h1>Lottery</h1>
</PageTitle>
...
Quando vemos o componente de “PageTitle”, é esperado que ele já retorne o estilo necessário para o título da página e não que seja apenas um invólucro para ele. Nesse caso, seria muito mais apropriado um nome como “PageTitleContainer”. O que nos leva a outro ponto: não tenha medo de nomes grandes.
É melhor gastar tempo uma vez escrevendo um nome grande do que perder tempo várias outras vezes decifrando o que aquela abreviação significa. Dessa forma, o tamanho de um nome deve ser proporcional ao escopo que ele pertence.
É fácil decifrar o que “name” significa dentro de um componente de formulário. Entretanto, é muito difícil saber o que aquele nome representa dentro de uma página de carrinho. Isto é, ele é o nome do produto? O nome do cliente?
Outro ponto em relação a nomes: não misture inglês com português.
É sempre bom manter um padrão e é mais aconselhável que se utilize nomes em inglês. Assim, as palavras chaves das linguagens já são em inglês e nomear as partes do seu código em inglês ajuda tanto a manter a organização quanto a escalabilidade do código.
Isso porque, as vezes, seu projeto pode chegar a Devs de fora do Brasil e eles não vão saber o que a variável “corDoCarro” significa. Portanto, o Google tradutor é muito bom hoje em dia, use e abuse dele.
A sopa de Divs
Quem utiliza o React JS, sabe que cada componente funcional deve retornar apenas um elemento JSX. A questão é que, na maioria das vezes, não temos apenas um único elemento para retornar. Ou seja, isso nos obriga a utilizar uma tag invólucro, que geralmente é uma div.
Mas qual o problema disso? Isso vira um problema quando temos uma página com muitos componentes filhos que, por sua vez, tem mais componentes filhos e por aí vai.
O resultado disso é uma verdadeira sopa de divs. Então, a solução para isso são os Fragments do React, que são um invólucro para o código JSX sem adicionar um novo elemento HTML à página.
import { Fragment } from "react";
const Element = () => {
return (
<Fragment>
<h1>Title</h1>
<p>Description</p>
</Fragment>
);
};
export default Element;
Ou simplesmente:
const Element = () => {
return (
<>
<h1>Title</h1>
<p>Description</p>
</>
);
};
export default Element;
Atualização de estados
Quando precisamos atualizar um estado do React com base no estado anterior, não é uma boa prática pegar esse valor da variável de estado.
const updateCount = () => setCount(count + 1);
Ao invés disso, é recomendado passar uma função que recebe o estado anterior e atualizá-lo com esse valor. Assim, isso evita que o React se perca nos fluxos de Renderização.
const updateCount = () => setCount((prevState) => prevState + 1);
Organizando importações
Em uma página onde você possui diversos componentes e precisa importar todos eles, você vai acabar com algo desse tipo:
import React from 'react';
import Header from 'components/Header';
import Card from 'components/Card';
import Button from 'components/Button';
import NumberSelector from 'components/NumberSelector';
import GameSelector from 'components/GameSelector';
...
Em contrapartida, você pode criar uma página ‘index.ts’ dentro da pasta ‘components’ e de lá exportar todos os componentes.
import Header from 'components/Header';
import Card from 'components/Card';
import Button from 'components/Button';
import NumberSelector from 'components/NumberSelector';
import GameSelector from 'components/GameSelector';
export {Header, Card, Button, NumberSelector, GameSelector};
Assim, no componente de página, você vai ter algo como isso:
import { Header, Card, Button, NumberSelector, GameSelector } from 'components';
Veja quantas linhas de código você economizou!
Comentários
O melhor comentário é aquele que não existe. Por isso, comentários só devem ser utilizados em último caso. Isso porque, geralmente, eles estão lá para explicar um código que não se explica por si só.
Como melhorar o seu Clean Code?
No livro “Clean Code” é citada a “Regra do Escoteiro”. Em suma, essa regra fala para você deixar o código sempre melhor do que achou.
Por isso, achou uma variável com um nome esquisito? Refatore. Achou uma função grande demais? Refatore. Assim, pouco a pouco o código vai ficando melhor.
No final das contas, ter um Clean Code não é algo que se aprende do dia para a noite, requer prática. Dessa forma, lembre-se: um código perfeito não existe, sempre vai ter algo a ser melhorado.
Autora: Jaiane Souza Oliveira.
Veja Também:
O que é Apache Kafka
Comments (2)
TypeScript: quando utilizar Alias ou Interface? - Luby Software do seu jeito
[…] ou linguagem de programação? Sendo as duas similares e, muitas vezes, intercambiáveis. As linguagens de programação fornecem diversas ferramentas para solucionarmos os problemas e, frequentemente, surgem dúvidas […]
Gerenciador de Pacotes: entendendo npm, npx e yarn no Node Package Managers – Luby Software
[…] cenário de desenvolvimento utilizando JavaScript/TypeScript, é impensável a construção de aplicações profissionais sem a utilização de um […]
Comments are closed.