Skip to content

Instantly share code, notes, and snippets.

@reginadiana
Last active June 12, 2025 14:56
Show Gist options
  • Save reginadiana/dcec1f54209b7fdf5e32ad7a5cfeef98 to your computer and use it in GitHub Desktop.
Save reginadiana/dcec1f54209b7fdf5e32ad7a5cfeef98 to your computer and use it in GitHub Desktop.
Anotações do Notion

  • Code smells: problemas de código

  • Cláusulas guardadas

    // Antes
    async function sendEmailCampaign(campaign) {
      if (!campaign.sent) {
        const recipients = await repository.getRecipients(campaign.id);
        if (hasEmailQuota(recipients.length)) {
          for (const recipient of recipients) {
            if (lisBouncedRecipient(recipient)) {
              if (isAllowedRecipient(recipient)) {
                await send(campaign, recipient);
              }
            }
          }
        }
      }
    }

    A ideia é que demos um break o quanto antes no código:

    async function sendEmailCampaign(campaign) {
      if (campaign.sent) return;
    
      const recipients = await repository.getRecipients(campaign.id);
      if (!hasEmailQuota(recipients.length)) return;
    
      for (const recipient of recipients) {
        if (!lisBouncedRecipient(recipient)) continue;
    
        if (isAllowedRecipient(recipient)) {
          await send(campaign, recipient);
        }
      }
    }

Outras dicas

  • Remover comentários desnecessários. Geralmente eles são escritos porque a nomenclatura não está clara
  • Remover linhas em branco
  • Evitar números mágicos, adicioná-las em constantes
  • Declarar variáveis perto de onde serão usadas
  • Separar em métodos
  • Um dos erros mais comuns é declarar um método que retorna mais ou menos do que ele promete.
  • A maneira com que escrevemos o código também pode gerar sobrecarga cognitiva
  • Se uma variável contém uma data, termine-a com _on, mas se tiver uma data com hora, termine-a com _at

  • Fundamentos

    Internet

    Rede de dispositivos computadorizados de alcance mundial. Surgiu na década de 60 durante a Segunda Guerra em projetos acadêmicos, mas o seu uso popular aconteceu na década de 80.

    Web

    É uma funcionalidade da internet para navegar através do hipertexto.

    Protocolo

    É um conjunto de regras para que os dispositivos se comuniquem.

    DNS

    É um sistema de nomes de domínios que associam um nome amigável (ex: google) ao seu endereço real (IP) que na maioria das vezes é dinâmico. São os servidores de DNS que fazem essa tradução e permitem um acesso mais fácil ao recurso web.

    CDN

    Armazena os dados estáticos de um site (ou seja, os que não mudarão com tanta frequências como imagens e videos) em cache para que quando o usuário acesse pela segunda vez o carregamento seja mais rápido.

    Ela captura o seu IP local e requisita os dados no data center mais próximo dele geograficamente falando, protegendo contra picos de tráfico, reduzindo custos com infraestrutura e banda larga, além de transmitir os dados de forma criptografada (SSL).

    Ele funciona como um proxy reverso, repassando o tráfego de rede para um conjunto de servidores em data centers ao redor do mundo.

    O erro 504 pode ser causado por falhas na CDN ou DNS, além de poder ser gerado por banco de dados corrompido.

    Servidor

    contém todas as informações, arquivos e códigos do site para disponibilizar o acesso ao publico.

    HSTS

    é uma especificação que dá aos sites a chance de dizer se preferem ser acessados somente via conexão segura. É enviado um metadado no cabeçalho da requisição. Se não for configurado, é possível acessá-lo com http://...

    Cache

    é uma cópia local dos arquivos que o servidor envia, mas ele expira depois de um tempo. O servidor decide se deve enviar todo o conteúdo novamente ou apenas uma resposta 304 (não modificado), dizendo ao navegador que ele pode entregar o mesmo conteúdo ou renovar os dados de cache que já existem.

    Buffer Overflow

    é um tipo de ataque que pode ser prevenido executando verificações de tamanho e intervalo (range) em todos os dados de entrada e saída que a sua aplicação lida.

    XSD

    é um schema no formato xml usado para definir a estrutura de dados que será valida. Ele funciona como uma documentação de como deve ser montado o SOAP Message que será enviado através do web service.

    Rest: É um estilo de arquitetura de software que define a implementação de serviços web. Podem trabalha com os formatos xml, json, entre outros.

    • Vantagens:
      • Permite integrações entre aplicações e também entre cliente e servidor em páginas web e aplicações.

      • Utiliza dos métodos http para definir a operação que está sendo efetuada

      • Fácil compreensão

        image.png

    Status HTTP

    Status Descrição geral
    1xx Informativo
    2xx Sucesso
    3xx Redirecionamento
    4xx Erro do Cliente
    5xx Erro do Servidor

    Características de um monólito

    1. Baixa complexidade
    2. Monitoramento simplificado
    3. Stack única
    4. Compartilhamento de recursos
    5. Acoplamento
    6. Escalabilidade mais complexa

    Características de um microserviço

    1. Stack dinâmica
    2. Mais fácil de ser escalado
    3. Acoplamento
    4. Monitoramento mais complexo
    5. Provisionamento mais complexo

    Web Services

    São serviços para aplicações se comunicarem independente de linguagem, software e hardware utilizados. Inicialmente foram criados para troca de mensagens utilizando a linguagem XML sobre o protoloco hhtp, sendo identificado por URI. Podemos dizer que web services são API's que se comunicam por meio de redes sobre o protocolo HTTP.

    SOAP

    É um protocolo simples de acesso ao objeto, baseado em XML para acessar serviços web principalmente por HTTP. Pode-se dizer que SOAP é uma definição de como web services se comunicam. Foi desenvolvido para facilitar integrações entre aplicações independente de linguagem, plataforma ou software, pois usa o XML como linguagem comum de comunicação.

    Ele possui meio de transporte genérico, ou seja, pode ser usado por outros protocolos além do HTTP.

    O SOAP Message possui uma estrutura única que deve sempre ser seguida:

    image.png

    WSDL

    Funciona como um contrato do serviço do web service. A descrição é feita em um documento XML, onde é descrito o serviço, especificações de acesso, operações e métodos.

    Segurança

    • De 3 a cada 4 sistemas tem problemas de vulnerabilidade por conta da exposição de dados sensíveis e informação critica no código.

    • Não é uma boa prática usar a ultima versão das imagens.

    • Estrutura de uma URL

      image.png

      • Protocolo diz como acessar
      • Domínio diz onde acessar.
      • Caminho diz em qual parte acessar.
      • Uma URI é um localizador e uma URL prove informações de como o recurso pode ser acessado.
    • Processo de uma requisição

      1. Ao digitar um endereço, temos uma URl (identificador) e HTTP (protocolo de transferencia).
      2. Uma comunicação é iniciada via protocolo TCP (garantindo que os pacotes cheguem ao destino) entre o computador (cliente) e o servidor (máquina que recebe o pedido e envia a resposta).
      3. O endereço (domínio) é convertido em IP (endereçamento de computadores) via DNS.
      4. O pedido é percorrido pelos proxies, que são dispositivos físicos como o moden, roteador e outros computadores para enviar os pacotes.
      5. Quando o pedido chega ao servidor, ele é analisado e se for aceito, volta pelo mesmo caminho.
  • Hardware

    Periféricos

    São dispositivos de entrada e saída do computador como mouse, monitor, teclado, etc.

    Firmware

    É o software presente nos perifericos

    Drivers

    Fazem a ponte entre um periférico e o computador. Cada um tem o seu.

    Memória RAM

    É uma placa que armazena dados temporariamente. Ao salvar os dados, eles são transferidos da RAM para o HD ou SSD (outros dispositivos de armazenamento) para sempre, pois se não fizermos isso e desligar a máquina, todos os dados serão limpos. Todos os programas do computador possuem e quando o computador "trava" é porque ela está cheia.

    Processador

    Transforma informações em código binário, ele é como se fosse o cérebro do computador.

Error in user YAML: (<unknown>): did not find expected alphabetic or numeric character while scanning an alias at line 1 column 3
---

- **Arquitetura Hexagonal:** explica que é importante separar em termos de design, as camadas de `resource` que lida com acesso a dados, `application` que lida com as regras de negocio e `drive` que lida com a API.

- **Design:** tem a ver com a separação de responsabilidades, camadas, patterns para resolver problemas comuns e **arquitetura** tem a ver com linguagem, framework, tipo de banco de dados, etc.

- **DAO (Data Access Object):** é um padrão de projeto que encapsula o acesso aos dados em uma camada separada, permitindo que a lógica de negócios não tenha conhecimento direto das operações de acesso aos dados. Isso significa que a lógica do negócio permanece agnóstica em relação ao tipo de banco de dados ou a tecnologia de persistência usada, o que tem várias vantagens.

- **Interface:** nos permite testar de forma isolada os drivers e resources sem que tenha um acoplamento da regra de negócios. Chamamos isso de `driver port`. Já os métodos que serão utilizados, ora batendo na camada de resource, ora simulando o comportamento com dados em memória (mocks), são chamados de `adapters`. Dai vem o conceito de `ports and adapters` na arquitetura hexagonal

- **Buffer:** é um array de bits que representam um dados
- **Design Patterns:** é focado na descoberta e na documentação de soluções reutilizáveis para problemas já existentes. Cada contexto merece seu *pattern*, e isso não é uma regulamentação.

---

Sobre padrões

Os padrões mais básicos e de baixo nível são comumente chamados idiomáticos. Já os padrões mais universais e de alto nível são os padrões arquitetônicos, que podem ser usados para arquitetar toda uma aplicação.

  • Padrões Criacionais:
  • Padrões Estruturais:
  • Padrões Comportamentais:

  • Um projeto com bom um design diminui a demanda de recursos humanos. Se adicionar releases for algo cada vez mais custoso em termos de tempo, complexidade e desenvolvedores, o design é ruim.

As diversas formas em que os dados são organizados e agregados é chamado de estrutura de dados

Métodos das estruturas

  1. Inserir ou excluir elementos
  2. Buscar e localizá-los
  3. Ordenar/classifica-los de acordo com determinada ordem

Características

  1. Podem ser lineares (arrays) ou não lineares (grafos)
  2. Homogênea (toda estrutura possui o mesmo tipo) ou heterogênea (com tipos diferentes)
  3. Estáticos (possuem tamanho/capacidade de memória fixa) ou dinâmica (podem expandir)

Arrays

Normalmente trabalhamos com apenas um tipo de dado, embora linguagens como o javascript permitam a mistura de vários tipos em um único array.

Características gerais

Na maior parte das linguagens, os arrays tem tamanho fixo

🎲 Todos os elementos ocupam espaço sequencial na memória

🎲 Inserir ou remover elementos do meio do array não é tão simples

🎲 São muito eficientes para acessar dados

🎲 Não são muito eficientes quando falamos de memória, pois ao declararmos um com tamanho de 10 indexes por exemplo, por mais que preenchamos apenas 2 deles, o restante dos indexes ficarão reservados para que no futuro sejam preenchidos, por mais que isso possa não acontecer. Portanto, o ideal é utilizar os arrays quando sabemos a quantidade de dados que queremos guardar.

🎲 Adicionar e remover um elemento no final do array ao invés do inicio ou meio é menos custoso

Pilha

Podemos fazer uma associação com uma pilha de pratos ou livros. Se quisermos adicionar ou remover algum item, precisamos fazer isso de cima pra baixo, o que corresponde do final para o inicio quando falamos de dados. Essa estrutura é utilizada, por exemplo, na navegação do browser.

Fila

Tem semelhança com a pilha, porém podemos remover o tem do inicio da filha e adicionar ao final. Podemos pensar em uma fila de cinema, onde quem chegou primeiro, sai primeiro da fila, mas quem chega por ultimo, sai por ultimo dela.

Deque

É uma junção das estruturas pilha e fila, que aceita inserção e remoção de elementos tanto no inicio como no final.

Fila circular

Busca resolver uma limitação da fila linear, que é lidar com espaços vazios que podem se enfileirar após a retirada de elementos no inicio da fila.

Lista ligada

Utiliza ponteiros para "apontar" para o endereço de memória mais próximo, sem que ele precise estar lá. Essa estrutura é bastante utilizada em alguns de fotos e playlists de musicas ou videos.

Conjuntos

São listas não ordenadas de elementos que não podem se repetir. No javascript, podemos instanciar essa estrutura com new Set()

Dicionário

É uma estrutura que guarda dados pares de chave e valor. Podem ter performance melhor em buscas e manipulação de dados do que objetos, pois utilizam referencias para as chaves de forma similar aos ponteiros.

Arvore

É uma estrutura não sequencial, muito útil para armazenar dados de forma hierárquica e que podem ser acessados de forma rápida, levando a uma maior eficiência na manipulação de dados.

Heap Binário

É um tipo especial de árvore binária, normalmente utilizada em computação para implementar filas de prioridade, indexação de banco de dados e em algoritmo de ordenação heap sort.

Grafo

É uma estrutura não sequencial que forma uma rede que interliga todos os dados, sendo utilizada pelas consultas do GraphQL, sistemas de navegação (gps/mapas) e algoritmo de caminho mínimo para rotas.

Streams

É uma forma de representar uma sequencia de bits, como um array por exemplo, sem precisar armazenar na memória, sendo muito útil em desenvolvimento com grande massa de dados.


Esse programa abaixo vai pegar todos os processos em execução e gravar no arquivo processos.txt

#!/bin/bash
# Nosso primeiro programa em Shell Script

mkdir ~/relatorio
ps aux > ~/relatorio/processos.txt
echo "Primeiro programa executado"

#!/bin/bash deve ser colocado no inicio do arquivo e indica que o nosso arquivo vai ser executado pelo programa bash que está localizado em /bin

mkdir cria um diretório chamado relatório a partir da HOME

ps aux lista todos os processos de forma detalhada

> indica a saída/resultado do comando, que no caso irá para o arquivo processos.txt

echo irá printar uma mensagem no terminal

Para visualizar o conteúdo do arquivo, podemos executar:

vim processos.txt

O que podemos fazer agora é colocar esse script em um arquivo do tipo .sh, você pode fazer isso com:

touch my_first_script.sh

Para executar esse arquivo de scripts, basta que executemos da seguinte forma:

./my_first_script.sh

Porém, o resultado será:

zsh: permission denied: ./my_first_script.sh

Isso porque o seu usuário não tem a permissão necessária para executar esse arquivo. Para saber quais permissões ele possui, basta executar:

ls -l process.sh # -rw-rw-r-- 1 rebase rebase 96 Feb  6 17:45 process.sh

Vamos entender o que significa essa resposta:

  • rw-rw-r--

Temos 3 tipos de permissão:

r, do inglês, read, leitura

w, do inglês, write, escrita

x, significa execução

Essas permissões podem ser agrupadas, de modo com que os usuários possam fazer várias coisas ou apenas uma:

Permissão Significado
--- Nenhuma permissão de acesso, quer dizer que o usuário não pode fazer nada
--x Permissão de execução
-w- Permissão de escrita
-wx Permissão de escrita e execução
r-- Permissão de leitura
r-x Permissão de leitura e execução
rw- Permissão de leitura e escrita
rwx Permissão de leitura, escrita e execução

Temos também níveis de acesso, que correspondem:

  1. Permissões especiais
  2. Permissões do dono/usuário quem criou o recurso
  3. Permissões do grupo (conjunto de usuários que pertencem ao mesmo grupo do dono)
  4. Permissões de outros usuários, que não se encaixam nos casos acima.

O 1º caracter (-) indica qual é o tipo do objeto (vale lembrar, que o objeto em questão é o arquivo que criamos), que no nosso caso se trata de um arquivo comum.

Os 2º, 3º e 4º caracteres seguintes (rw-) representam as permissões do dono do objeto, que no nosso caso se trata de leitura e escrita.

Os 5º, 6º e 7º caracteres seguintes (rw-) significam a mesma coisa do item acima, mas valem para os usuários do mesmo grupo.

Os 8º, 9º e 10º caracteres seguintes (r--) significam os outros usuários, possuem apenas permissão de leitura.

Como foi você quem criou o arquivo, se enquadra como dono dele, apenas com permissão de leitura e escrita. Portanto, não pode executá-lo. Para mudar isso, execute:

chmod 777 my_first_script.sh

Verifique novamente as permissões, e o resultado será:

-rwxrwxrwx 1 rebase rebase 96 Feb  6 17:45 my_first_script.sh

Perceba que agora os três primeiros caracteres após o primeiro correspondem a rwx (leitura, escrita e execução). Agora sim podemos executar o arquivo. Se a mensagem que definimos lá no começo for mostrada no terminal, quer dizer que deu tudo certo.

Executando uma operação básica

#!/bin/bash

echo "Contando linhas..."
sleep 5

LINHAS=`cat ./processos.txt | wc -l`
echo "Existem $LINHAS no arquivo"

Esse programa é uma continuação do que já fizemos, onde ele vai basicamente puxar a quantidade de linhas do arquivo txt e mostrar na tela. O comando cat vai pegar o arquivo e o comando wc -l vai retornar a quantidade de linhas dele. Já o uso do $ serve para referenciar a variável que criamos. De diferente temos o comando sleep, que irá esperar um tempo em segundos antes de continuar a executar os comandos seguintes.


Removendo um diretório não vazio e privado:

sudo rm -r ./<dir_name>

Reinstalando um pacote deb:

sudo dpkg -i ./<deb_file_name>.deb

Renomeando o nome de todos os arquivos de um diretório

for f in *.tsx; do mv -- "$f" "${f%.tsx}Icon.tsx"; done

Introdução de React

JSX não é html. Ele é apenas uma sintaxe para React.createElement. Então, todo jsx que for escrito será convertido para React.createElement, e quem faz essa conversão é o babel. O jsx não pode ser interpretado pelo browser.

document.createElement

Retorna um elemento DOM

React.createElement

Retorna um objeto que representa o elemento DOM (virtual)

ReactDOM

É a lib que atualiza a verdadeira DOM baseado nas mudanças da DOM virtual.

Reconciliation

É o processo de sincronizar o virtual DOM com o DOM real durante os processos de renderização e re-renderização dos componentes.

Single Page Aplication

Significa que temos uma única página que fará as alterações quando necessário. É assim que o React funciona.

  • Alterar a DOM diretamente é um processo custoso para o React e consequentemente diminui a performance das nossas apps

Code Splitting

Dividir o código pode te ajudar a carregar somente o necessário ao usuário, o que pode melhorar drasticamente o desempenho de sua aplicação. A função do React.lazy é permitir a renderização

React Strict Mode

Esse "modo estrito" invoca duas vezes a renderização dos componentes quando o estado é atualizado, a fim de evitar efeitos colaterais.

  • Patterns

    1. Preferir usar componentes funcionais, a menos que precisemos de algo que ele não tenha, como state interno, lifecycle e event handles.
    2. Manter componentes pequenos, para que seja mais fácil de testar, ler, dar manutenção e reaproveitar.
    3. Usar o defaultProps e o a lib prop-types para definir valores default para as props e seu tipo, além de especificar se alguma props é obrigatória por exemplo. Isso é interessante caso não esteja usando Typescript
    4. Não use o index como key ao iterar elementos que podem mudar a ordem. Ao invés disso, podemos usar o próprio id.
    5. Prefira não iniciar o estado de um componente com um dado vindo como props de um componente pai. Primeiro porque teremos 2 fontes da verdade (a props, e o estado inicializado), e segundo porque, se por algum motivo essa props mudar, o estado não será "re-inicializado" ou "atualizado", pois o state já foi inicializado e isso só acontece uma vez.
  • hooks

    useState

    É é um hook que define uma variável reativa. Toda vez que o setState é chamado, o componente é atualizado. Por isso, o setState sempre precisa ser chamado por algum evento prévio como o onChange, onClick, etc. Caso contrário, teremos renderizações infinitas.

    A definição do estado inicial pode ser feita usando um callback, assim como ao atualiza o estado (neste caso, teremos acesso ao estado anterior antes do componente ser atualizado).

    A diferença ao utilizar o useState invés de uma variável comum é poder dizer ao React que quando essa variável mudar ele precisa renderizar novamente os componentes dependentes dela.

    Esse método é muito útil quando queremos atualizar o state para um novo valor que dependa do anterior.

    // Ao invés disso
    this.setState({ showPagination: !this.state.showPagination });
    
    // Prefira
    this.setState(( state, props) => {
      return { showPagination: !state.showPagination };
    ));

    useEffect

    É um hook que permite executar algo dependendo do estado de ciclo de vida do componente.

    useEffect(() =>
      console.log("Vou ser chamado toda vez que o componente for montado e/ou atualizado")
    ) // É executado apenas uma vez

    Porém, se adicionarmos uma chamada de atualização de estado nesse caso, causaremos um loop infinito

    const [isLoading, setIsLoading] = useState(false);
    
    useEffect(() =>
      setIsLoading(prev => !prev) // Atualiza compontente
    ) // É executado toda vez que o componente é renderizado, pois não há dependencias
    useEffect(() =>
      console.log("Vou ser chamado toda vez que o componente for montado")
    , []) // Não tem dependencias. É executado apenas uma vez
    
    useEffect(() =>
      console.log("Vou ser chamado toda vez que o estado for atualizado")
    , [estado]) // Depende do estado. Se receber mais estados, o effect será acionado quando qualquer um dos estados sofrer alteração
    
    useEffect(() => {
      return () => {
       console.log("Vou ser chamado toda vez que o componente for desmontado")
      }
    });
    
    • Quando precisamos realizar alguma ação que depende do estado dentro do useEffect, ele precisa ser usado como dependência para que seja chamado
    • Porém, não é uma boa chamar o set para atualizar o estado que está como dependência, porque assim o useEffect vai ser chamado o tempo todo
    • Podemos ter vários effects em um componente, e é uma boa prática separá-los que as funções e dependências tem responsabilidades diferentes.
    • Só pode retornar funções. Ex: quando declaramos um async logo de cara ele gera um erro pois entende que estamos tentando retornar uma premisse e não uma função.
    • É executado após a renderização do componente. E ao realizar requisições dentro dele, estamos fazendo com que o processo de carregamento da página seja mais lento. O ideal é que as requisições possam ocorrer em paralelo com a montagem. Uma das formas de se fazer isso é usando o useQuery.
    • Ele nos obriga a colocar no array de dependências todos os valores que sejam reativos, sejam eles props, estados, etc., a menos que transformemos esses dados em não-reativos.
    • É uma boa prática de performance não fazer manipulação de dados dentro do useEffect, mas sim no topo do componente.

    useRef

    É uma maneira do React pegar um elemento .jsx como referencia, ou seja, toda vez que quisermos pegar determinado elemento via documentGetElementById, ou querySelect, podemos simplesmente usar o useRef para isso.

    O legal do useRef é que ao atribuirmos um valor para ele e atualizarmos o componente por algum motivo, ele não se perde, diferente de quando declaramos esse mesmo valor em escopo global usando var, let ou const.

    O objeto retornado persistirá durante todo o ciclo de vida do componente.

    • O componente não é atualizado quando valor de useRef muda. Se quisermos, podemos usar um callback pra ser chamado quando isso ocorrer.
  • Contextos

    O context API é nativo a partir da versão 16

    Criando um contexto no React

    const Context = React.createContext()

    Provider

    É um componente que "fornece" os dados do contexto, bem como as suas mudanças aos seus "consumidores" (componentes filhos deste provedor) do mesmo contexto.

    /* A props "value" precisa necessáriamente ter este nome */
    <Context.Provider value={value}>
    ...
    </Context.Provider>
    

    Consumer

    É um componente que recebe os dados do contexto. Seu componente filho espera receber uma função (que recebe as props) do contexto que retorne um componente. Se um componente consumer for renderizado sem um componente de provider como pai, as props recebidas serão as que formam informadas como default ao criar o contexto, e não as que foram enviadas pelo componente de Provider.

    <Context.Consumer>
    {(value) => <ChildComponent />}
    </Context.Consumer>
    

    Atualizando valores do contexto

    // Criando o contexto
    const ThemeContext = React.createContext({
      theme: 'black', // Caso de valor qualquer
      toogleTheme: () => {} // Futuro setState
    })
    
    // Provendo contexto
    const [theme, setTheme] = useState('');
    const value = {theme, setTheme}
    
    <ThemeContext.Provider value={value}>
    ...
    </ThemeContext.Provider>
    
    // Consumindo contexto
    
    <ThemeContext.Consumer>
    {(value) => <ChieldComponent /> }
    </ThemeContext.Consumer>
    
    // ChieldComponent
    // Atualiza contexto
    
    const UseThemeContext = React.useContext(ThemeContext)
    
    UseThemeContext.setTheme('white')
    
  • Bibliotecas

    • React PDF

      Recurso Descrição
      Page Representa uma única página
      Wrap Quebra de documento
      Breakble Components Tenta preencher todo espaço restante antes de pular para uma nova página
      Unbreakble Components Se não houver espaço suficiente no restante da página, o conteúdo será renderizado na página seguinte
      Break Força a quebra do documento para continuar na próxima página
      Fixed Renderiza algum componente em todas as páginas do documento, como por exemplo o cabeçalho e rodapé
      PDFDownloadLink Permite que seja feito o download do documento
      BlobProvider Habilita o acesso ao blob data
      usePDF É um hook customizado do React que nos dá acesso ao documento
    • React Hook Form

      Adota o uso de entradas não controladas em vez de depender do estado: apenas as alterações de entradas são re-renderizadas, não o formulário inteiro. Tecnicamente, ele usa ref por baixo dos panos, diferentes de outras libs que usam o state. Essa abordagem torna os formulários mais eficientes e reduz o número de novas renderizações.

      Em uma solução comum, usaríamos um useState para o campo e ao triggar o onChange do input atualizaríamos esse estado, fazendo com que o componente seja atualizado toda hora, comprometendo a performance.

      Aqui nós temos um caso de High Order Function, que é o ato de passar uma função como argumento para outra função

      handleSubmit

      Vai passar os dados do formulário quando a validação do formulário for bem-sucedida. É sempre chamada ao submeter o formulário.

      onSubmit

      Vai ser chamado quando o formulário for válido após ter passado pelo handleSubmit

      register

      Método que declara a validação para o campo e torna disponível o valor dele para ser usado no hook form. Dentro dele há todos os parâmetros que passaríamos para o input, como onChange, onBlur, etc.

      reset

      Apaga ou reseta o state do hook form, especificamente os valores e mensagens de erro.

      @hookform/error-message

      Fornece um componente para exibir as mensagens de erro que foram extraídas de useForm

      useController

      É um hook que funciona de forma similar a Controller, por meio do qual é possível passar as props diretamente para os campos do formulário, conforme o exemplo da documentação:

      O React Hook Form suporta validação de formulário baseada em schema (representação da estrutura de dados do formulário), como o Yup ou Zod. Para isso precisamos instalar a lib @hookform/resolvers

      O useForm prove o método formState, que prove dentro dele os seguintes métodos:

      isDirty

      Indica se o evento dirty ocorreu para qualquer um dos campos

      dirtyFields

      Objeto que retorna os campos que sofreram a ação de dirty

      isValid

      Indica se o formulário está valido

      errors

      Objeto que contém chave (name do campo) e valor (erro do campo)

      isSubmitted

      Indica se o usuário submeteu o formulário pelo menos uma vez

      touchedFields

      Objeto que contém os campos que sofreram a ação de touched. Vale lembrar, que touch significa que o usuário interagiu com o campo de forma "superficial", seja clicando nele, selecionado com tab, etc., mas isso não significa que o campo esteja dirty, pois isso só ocorre quando um valor é inserido de fato.

      Lidando com arrays

      Temos o useFielddArray

      • Usar o field.id que é gerado automaticamente por ele como key, e não o index.
    • Zod

      • Podemos fazer transformações de dados usando o método .transform
      • O Zod só trabalha com tipos primitivos do javascript como boolean, string, number, etc. Se quisermos algo diferente podemos usar o .instanceOf

      .refine

      Retorna o dado especificamente do campo que foi chamado. Podemos adicionar validações customizadas para ele.

      .superRefine

      Retorna os dados de todos os campos. Podemos adicionar validações customizadas para o campo que foi chamado que dependa dos valores de outros campos do formulário.

    • React Router DOM

      window.location
      
      location
      • Hooks

        useRouteMatch()
        
        useLocation()
        
        useHistory()
        
        matchPath()
        
        useParams()
        
        generatePath()
        
      • Componentes

        <Router />
        
        <Switch />
        
        <Suspense />
        
        <Link />
        
        <NavLink />
        
        <Redirect />
        
        <BrowserRouter />
        
  • Bundler

    Webpack

    É um empacotador de módulos para aplicações JS em um único arquivo. Ele suporta fontes, css, imagens, html, javascript e plugins.

    Entry

    Utilizando grafo, o webpack precisa de um ponto de entrada para buscar todos os módulos e dependências. Exemplo:

    entry: {
    	app: glob.sync("./vendor/**/*.js").concat(["./js/app.js"]),
    }

    Output

    Para determinar quais são os módulos que ele vai exportar. Exemplo:

    output: {
     filename: "[name].js",
     path: path.resolve(__dirname, "../priv/static/js"),
     publicPath: "/js/",
    }

    Loaders

    Para permitir que o webpack gerencie arquivos que não são do tipo javascript. Ele também pode converter a versão do javascript. Exemplo:

        module: {
          rules: [
            {
              test: /\\.vue$/, // Define os arquivos que serão filtrados, filtra todos os arquivos com extensão .vue
              exclude: /node_modules/,
              loader: "vue-loader",
            },
            {
              test: /\\.js$/, // Filtra todos os arquivos com extensão .js
              exclude: /node_modules/,
              use: { // Define os módulos que serão utilizados
                loader: "babel-loader",
              },
            },
            {
              test: /\\.[s]?css$/,
              use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"],
            },
            {
              test: /\\.svg$/i,
              type: "asset/inline",
            },
            {
              test: /\\.(png|jpg|jpeg|gif)$/i,
              type: "asset/resource",
            },
            {
              test: /\\.(woff|woff2|eot|ttf|otf)$/i,
              type: "asset/resource",
            },
          ],
        },

    Plugins

    Podem ser usados para otimização de pacotes, mimifição, injeção de scripts e injeção de variáveis de ambiente. Exemplo:

        plugins: [
          new MiniCssExtractPlugin({ filename: "../css/app.css" }),
          new CopyWebpackPlugin({
            patterns: [{ from: "static/", to: "../" }],
          }),
          new webpack.DefinePlugin({
            'process.env.BUILD': JSON.stringify('web')
          }),
          new VueLoaderPlugin(),
        ],

    Mode:

    Utilizado para abordagem de configuração do zero. É possível configurar módulos como produção (trás otimizações internas e gera um arquivo final) ou desenvolvimento. O default é desenvolvimento. Exemplo:

    mode: options.mode || "production",

    Stateful

    Usa estados, possui gerenciamento de estados no componente e é construído usando classes em JS. É o ciclo de vida no React

    Stateless

    Não usa estados, não possui gerenciamento de estados no componentes e é construído usando funções em JS. Usado para renderizar imagens, textos comuns, etc.

    Formulários matem um estado interno ao próprio DOM


  • Pirâmide de testes

    Em uma pirâmide de testes, testes e2e são mais abrangentes do que eficientes, e testes unitários são mais eficientes do que abrangentes. Isso significa que faz mais sentido estressar os testes de unidade com vários cenários do que e2e.

    • Testes de unidade: não possuem qualquer interação com recursos externos como um banco de dados, API ou sistema de arquivos. Podem testar coisas em isolamento ou conjunto de classes.
    • Testes de integração: testam componentes que pertencem a múltiplas camadas, como drivers e applications, se comunicando com serviços externos que podem ser mocados ou não.
    • Testes e2e: tentam ao máximo simular o comportamento de produção e acessam de verdade os recursos externos. Mesmo nessa camada podem existir comportamentos mocados, não queremos emitir uma NF, enviar emails ou processar pagamentos de verdade por exemplo.
  • Simuladores

    • Teste double é um padrão que tem o objetivo de substituir um DOC (depdended-on component) em um determinado tipo de teste que acesse recursos externos por questões de performance (por que alguns recursos podem ser lentos) ou segurança (porque não é trivial ficar mandando email, processando pagamento ou emitindo NF de forma recorrente).

    • Mocks são um tipo de teste double, mas nem tudo é mock.

    • Dummy são objetos que criamos para completar uma lista de parâmetros para invocar um método. Os valores dos parâmetros enviados não tem influencia no resultado do teste.

    • Stubs são objetos que retornam um valor pré-definido para um método. Ex: método que retorna a cotação do dólar. Podemos usar o sinon ou jest por exemplo:

      sinon.stub(AccountDAODatabase.prototype, "saveAccount").resolves();
      sinon.stub(AccountDA0Database.prototype, "getAccountByEmail")
      	.resolves(null);
      sinon.stub(AccountDAODatabase.prototype, "getAccountById")
      	.resolves(input);
    • Spy espiona a execução para saber se o que você queria que acontecesse, aconteceu:

      const sendSpy = sinon.spy(MailerGatewayMemory.prototype, "send");
      
      expect(sendSpy.calledOnce).toBe(true);
      expect(sendSpy.calledwith(input.email, "Welcome!", "")).toBe(true);
    • Fake é uma implementação que simula o comportamento original. Ex: DAO

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment