Aumentando a legibilidade do código
A maioria das dicas apresentadas neste artigo dependerá do ES6 (ECMAScript 2015) sintaxe
Desestruturando
A desestruturação pode ser útil para retirar itens individuais de um objeto ou array. Tenha cuidado ao usar com arrays, pois você pode se confundir facilmente renomeando alguma propriedade de maneira errada, vamos dar uma olhada em um exemplo:
_14// alunos => [idade, série]_14const alunos = [_14  [19, 80.9],_14  [21, 75.2],_14  [19, 88.7]_14]_14_14alunos.forEach(([idade]) => idade) // 19, 21, 19_14_14// Mesmo renomeando o primeiro valor como nota, obtemos a idade_14alunos.forEach(([série, idade]) => série) // 19, 21, 19_14_14// Podemos pular valores de uma array usando uma vírgula (,)_14alunos.forEach(([, nota]) => nota) // 80.9, 75.2, 88.7
Agora usando um objeto.
_14const alunos = {_14  Kevin: {_14    idade: 19,_14    nota: 80,9,_14  },_14  Laura: {_14    idade: 21,_14    nota: 75,2,_14  },_14};_14_14const { Kevin } = alunos;_14_14Kevin.nota; // 80.9
Usando acessadores de propriedade
Podemos ter acesso a uma propriedade de duas maneiras, você pode usar o simples ponto ., ou a notação de acesso colchete [].
_6const Kevin = {_6  idade: 19,_6  nota: 80,9_6}_6_6Kevin['nota']) // 80.9
Um exemplo com CSS Modules: usando um nome de classe com caracteres especiais.
_3const Texto = () => {_3  return <p className={styles['primary-text']}>Olá!</p>_3}
Se desejar, você também pode acessar as propriedades dinamicamente:
_9const mensagensDeStatus = {_9  ERRO: 'servidor morreu',_9  CARREGANDO: 'Estamos dando o nosso melhor',_9  OCIOSO: 'Aguardando entrada'_9}_9_9const status = getCurrentStatus() // CARREGANDO_9_9mensagensDeStatus[status] // Estamos dando o nosso melhor
Usando parâmetros de função de objeto
Isso é situacional, mas geralmente quando tenho mais de 2 ou 3 parâmetros em uma função, uso esse método. Compare as funções abaixo:
_12const retorneListaRandomica = (tamanhoDaLista, variacaoDeConteudo, delayEmMS) =>_12  nova Promessa((resolve) => {_12    const numeroRandomico = () => Math.ceil(Math.random() * variacaoDeConteudo);_12_12    const arrayGerada = Array(tamanhoDaLista)_12      .fill(0)_12      .map((_) => numeroRandomico());_12_12    setTimeout(() => resolve(generatedArray), delayEmMS);_12  });_12_12retorneListaRandomica(8, 5, 2000).then((array) => array); // [4, 4, 5, 1, 4, 5, 1, 4]
Desculpe, não consegui pensar em nada melhor do que isso. Mas vamos agora dar uma olhada nos parâmetros em objetos.
_4const retorneListaRandomica = ({ tamanhoDaLista, variacaoDeConteudo, delayEmMS }) =>_4new Promise((resolve) => ... );_4_4retorneListaRandomica({ tamanhoDaLista: 8, delayEmMS: 2000, variacaoDeConteudo: 5 });
Agora, não nos perdemos em nossos parâmetros e não precisamos nos preocupar em ordená-los corretamente.
Dicionários
Às vezes, queremos traduzir alguns retornos ou receber uma mensagem por status. Os dicionários podem fazer isso facilmente sem escrever um monte de if statements.
Eles foram mencionados anteriormente em um bloco de código antes, então vamos retroceder.
_30const ifStatement = (status) => {_30  if (status === 'ERRO') return 'servidor morreu';_30  if (status === 'CARREGANDO') return 'Estamos tentando o nosso melhor';_30  if (status === 'OCIOSO') return 'Aguardando entrada';_30};_30_30ifStatement('ERRO');_30_30const switchCases = (status) => {_30  switch (status) {_30    case 'ERRO':_30      return 'servidor morreu';_30    case 'CARREGANDO':_30      return 'Estamos dando o nosso melhor';_30    case 'OCIOSO':_30      return 'Aguardando entrada';_30    default:_30      throw new Error(`Status: ${status}, não encontrado`);_30  }_30};_30_30switchCases('ERRO');_30_30dicionário const = {_30  ERRO: 'servidor morreu',_30  CARREGANDO: 'Estamos dando o nosso melhor',_30  OCIOSO: 'Aguardando entrada',_30};_30_30dicionário['ERRO'];
- If statements - Legibilidade média e 3 linhas
 - Switch cases - Legibilidade média e 7-9 linhas
 - Dicionários - Fácil legibilidade e 3 linhas
 
Arrow functions
As arrow functions têm suas desvantagens quando comparadas com as normais, mas você pode obter um bom resultado usando-as. Veja algumas comparações abaixo.
_16// Versão normal_16function dobrarValorF(valor) {_16  return value * 2_16}_16_16function retorneNomeDePessoasF(pessoas) {_16  return pessoas.map((pessoa) => pessoa.nome)_16}_16_16// Versão Arrow function_16const dobrarValorA = (valor) => valor * 2_16_16const retorneNomeDePessoasA = (pessoas) => pessoas.map((pessoa) => pessoa.nome)_16_16// Desestruturando_16const retorneNomeDePessoasA = (pessoas) => pessoas.map(({ nome }) => nome)
Usando-os, podemos fazer tudo em apenas uma linha e omitir os parênteses em torno dos parâmetros caso haja apenas um. Na linha 27, combinamos a desestruturação com arrow functions.
Guard clauses - Evitando o else
Quando usamos if statements, pretendemos cobrir todos os casos de que precisamos, consequentemente inundando nosso código com o else. Vamos pegar este exemplo que usa o return:
_9const verificarIdade = (idade) => {_9  if (idade < 18) {_9    return 'Não pode entrar na festa.'_9  } else if (idade >= 18 && idade < 21) {_9    return 'Pode entrar, mas não pode beber.'_9  } else {_9    return 'Pode entrar e beber.'_9  }_9}
Na função verificarIdade verificamos o input, e a lógica funciona assim:
- Se a pessoa estiver mais que 18 anos ela não pode entrar na festa.
 - Se tiver menos de 21 anos, mas 18 anos ou mais, pode entrar mas não beber.
 - Se forem mais velhos, podem entrar e beber.
 
Temos alguns problemas neste código que podemos corrigir:
- Na linha 4, não precisamos verificar se a pessoa tem mais de 18 anos porque já a retornamos na linha 2.
 - Precisamos apenas retornar uma mensagem, então nos podemos colocar a condição e a declaração de retorno em uma única linha, alguns programadores não gostam dessa forma, então use o que achar melhor para você.
 - Podemos substituir as palavras-chave else if e else por 
if statementse até mesmo omitir o else na última linha. 
Vamos refatorar e conferir.
_6const verificarIdade = (idade) => {_6  if (idade < 18) return 'Não pode entrar na festa.'_6  if (idade < 21) return 'Pode entrar, mas não pode beber.'_6_6  return 'Pode entrar e beber.'_6}
Veja como podemos usar as formas linha 2 ou linha 3-4 para retornar a mensagem, então use o que parecer melhor para você. Pessoalmente, para mensagens longas, uso o segundo método. Em conclusão, avalie se você precisa usar ou não uma keyword.
Quando não podemos evitar a keyword else
Normalmente, não podemos evitar o uso de else se precisarmos retornar a mesma coisa para ambas as condições.
_6const verificarCargos = (usuário) => {_6  if (user.isPremium) renderizarStatusPremium()_6  else renderizarAnuncios()_6_6  return renderizarInterfaceDoAplicativo()_6}
Operador Spread para passar props no React
Este operador é responsável por obter o restante de um objeto, vamos supor que precisamos mapear uma lista de usuários e retornar um componente de cada usuário. Esta é a lista de usuários:
_10const usuarios = [_10  {_10    nome: "Jorge",_10    idade: 72,_10    peso: 80,_10    altura: 182,_10    trabalho: "Caminhoneiro"_10  },_10  ..._10]
E agora o componente e os props.
Sem operador de spread:
_6const UserCard = ({ nome, idade, trabalho }) => <></>_6_6const app = () =>_6  users.map(({ nome, idade, trabalho }) => (_6    <UserCard nome={nome} idade={idade} trabalho={emprego} />_6  ))
Usando o operador spread:
_1const App = () => users.map((user) => <UserCard {...user} />)
Veja como sem precisar de todos os props, ainda podemos passar o operador spread para o componente. Mesmo desestruturando as props no primeiro exemplo, nosso segundo bloco de código dá muito mais legibilidade.
Short Circuit Evaluation
Às vezes, precisamos apenas de uma condicional curta para definir um valor de variável ou verificar uma condicional e, com o if statements gastamos muito espaço para coisas simples. Veja estes dois exemplos:
_6// declaração if_6if (estaEnsolarado) roupaEscolhida = RoupaDeVerao_6else roupaEscolhida = RoupaDeInverno_6_6// Short Circuits_6const roupaEscolhida = estaEnsolarado ? RoupaDeVerao : RoupaDeInverno
_5..._5_5if (estaEnsolarado && estouFeliz) return irParaPraia()_5_5...
Para obter mais informações sobre os Short Circuits, verifique os recursos adicionais no final do artigo.
Evite Short Circuits no React
Sim, eu sei que recomendei o uso de Short Circuits neste artigo, mas às vezes evitá-los pode nos dar uma melhor legibilidade em nosso código. Vejamos alguns exemplos
Short Circuits
_17const componente = ({ isAdmin }) => {_17  const [state, setState] = useState(false)_17_17  return isAdmin ? (_17    <AdminInterface>_17      <>_17        <></>_17      </>_17    </AdminInterface>_17  ) : (_17    <UserInterface>_17      <>_17        <></>_17      </>_17    </UserInterface>_17  )_17}
Declarações if
_20const componente = ({ isAdmin }) => {_20  const [state, setState] = useState(false)_20_20  if (éAdmin)_20    return (_20      <AdminInterface>_20        <>_20          <></>_20        </>_20      </AdminInterface>_20    )_20_20  return (_20    <UserInterface>_20      <>_20        <></>_20      </>_20    </UserInterface>_20  )_20}
Componentes individuais
_7const componente = ({ isAdmin }) => {_7  const [state, setState] = useState(false)_7_7  if (isAdmin) return <AdminInterface />_7_7  return <UserInterface />_7}
Componentes individuais e sem lógica interna
_2const componente = ({ isAdmin }) =>_2  isAdmin ? <AdminInterface /> : <UserInterface />
Exportando tudo do arquivo index
Esse é um truque legal de importação/exportação, que não tem nada a ver com nosso código real, mas podemos obter resultados interessantes usando-o. É assim que costumamos import arquivos:
_3import Cérebro from './Brain.png'_3import pasta from './BriefCase.png'_3import BuildingConstruction from './BuildingConstruction.png'
Agora usando um arquivo index dentro da pasta de imagens:
Veja como transformamos 3 linhas em 1. Observe que não precisamos usar public/Emojis/index, JavaScript importa automaticamente o arquivo se o nome dele for index.
Transformando condicionais complicadas em variáveis
Veja um exemplo em que estamos verificando vários condicionais para verificar se podemos renderizar o painel de gerenciamento:
_2if (user.roles.includes('ADMIN') || (user.age > 18 && user.reputation > 10))_2  return renderManagementPannel()
Vamos refatorar o código transformando os complicados condicionais em variáveis:
_4const isAdmin = user.roles.includes('ADMIN')_4const responsibleUser = user.age > 18 && user.reputation > 10_4_4if (isAdmin || responsibleUser) return renderManagementPannel()
Veja como aumentamos as linhas em nosso código, mas nossa equipe trabalhando no aplicativo pode saber facilmente porque a função renderManagementPannel está sendo acionada.
