SlideShare une entreprise Scribd logo
1  sur  71
Télécharger pour lire hors ligne
Escalando Apps
com React e
TypeScript
por Ruben Marcus
Um pouco sobre mim
● Atuo 10 anos com Desenvolvimento Web
● Atuo com React desde 2016. Com Next.js e TypeScript desde 2018.
● Já atuei em Portais e E-commerces com milhões de visitas diárias
● Atuo com foco em melhoria de código e performance de aplicações
● 31k pessoas leram minhas respostas no Stack Overflow
● 35k de leituras nos artigos do Medium e dev.to
● Já Atuei em Projetos de 5 Países, com pessoas de mais de 70 países.
O que você vai ver
nessa apresentação
▪ Quem deve Escalar?
▪ O que é Escalabilidade?
▪ Problemas Comuns
▪ Desafios
▪ Mantenabilidade
Escalabilidade
01.
▪ GIT
▪ Configurando um projeto
▪ Estrutura de Projetos
▪ Monitoramento
▪ Testes
Arquitetura
02.
▪ React + TS
▪ Boas Práticas de React e
TypeScript
▪ Solid com React e
TypeScript
React + TS
03.
Quem deve pensar em Escalar?
Qualquer pessoa que queira atuar em um
projeto que tenha um crescimento muito rápido
em sua base de código, e uma alta frequência
de atualização de seus co-criadores.
Quais problemas evitamos em
um projeto escalável?
- Custos de Infraestrutura.
- Alta curva de aprendizado de novos integrantes
- Performance
- Manutenabilidade
- Falta de Agilidade e Problemas de Entrega de
novas features
Como sabemos que um projeto
é escalável?
- O projeto consegue aumentar recursos de infra-estrutura sem aumentar
absurdamente os custos
- Estrutura do Projeto é simples e intuitiva
- Complexidade e Número de dependências não impede o crescimento do
projeto
- Aprendizado sobre o produto e base de código de novos integrantes ocorre
de forma orgânica e sem maiores dificuldades
- Projeto raramente têm bloqueios na parte técnica
- Projeto consegue atender uma base de usuários enorme, sem maiores
problemas.
- Projeto necessita de poucas refatorações para ser o mais performático
possível
Problemas comuns
de Escalabilidade
- Cada Desenvolvedor quer implementar seu estilo de código ou paradigma de
programação ( Programação Funcional x POO)
- Mudanças frequentes na estrutura de projeto ou estilo de código (ex: JSX para TSX
- Complexidade e Número de dependências que impede o crescimento do projeto
- Código que fere o princípio de Single Responsibility, e que se alterado pode quebrar
muitas partes do projeto.
- Código sem nenhuma documentação
- As Pessoas que fizeram a maior parte do projeto e tinham conhecimento sobre ele, já
deixaram a equipe.
- Projeto engessado com dependências muito antigas (ex: só compativel com IE)
Você define a cada decisão
se seu projeto vai ser
escalável ou não
Como saber se meu código
é escalavel?
Faça a si mesmo as seguintes perguntas:
- Meu código é legível, de fácil entendimento, performático (faz mais com menos
código), tem vazamento de memória?
- Já existe algum componente, função, método, serviço na aplicação que faz o que quero
fazer?
- Essa é a melhor forma de criar a estrutura de arquivos do meu código?
- Os custos para o navegador, usuário e servidor são grandes demais?
- Meu código implementa alguma melhoria, ou introduz bugs?
- O tipo de dados e objetos são coerentes com o fluxo da aplicação e não existe a
possibilidade de quebrar a mesma?
- Só eu entendo a lógica escrita?
- Consigo explicar esse código facilmente para qualquer novato na equipe?
Arquitetura:
Estruturando seu projeto
Existem diversas formas de estruturar um projeto React.
Você pode utilizar Atomic Design para fazer um projeto escalável.
Como pode utilizar uma estrutura de pastas muito semelhante ao CRA
( Create React App ).
Mas caso sua aplicação esteja ficando muito complexa, ou com
Componentes globais demais, talvez seja o momento de adotar uma
arquitetura Micro-frontend.
Ou criar uma lib para seus componentes de layout.
Ou dividir sua pasta em mais subpastas.
Arquitetura:
Estruturando seu projeto
Você pode descobrir se a arquitetura do seu projeto está ruim, se para
renderizar um componente em uma página, você depende de um
número muito grande de arquivos e dependências para isso.
O contrário também é válido, ter um componente gigantesco de mais
de 1000 linhas, em que o código fique gigantesco e difícil de debugar,
é um problema bem grande para escalabilidade.
Arquitetura: GIT
Na hora de decidir como sua equipe vai atuar em um projeto, pode-se usar
tanto um repositório por projeto, como mono-repos.
Dependendo do tamanho do seu projeto, mono-repos não é uma solução
viável, devido a performance baixa do Git para lidar com projetos grandes
em monorepos, e a problemas de segurança que um projeto pode estar
exposto ao estar em um mono-repo.
Como padrão de branches,recomendo o Gitflow.
Como padrão de commits, recomendo usar Conventional Commits.
Para fazer releases: Semantic Release.
Configuração:
Paths
Quando estamos configurando um Projeto React + TS, algumas práticas que
considero vitais para que um app seja escalável:
- Configurar os paths no arquivo tsconfig.json, por exemplo:
Configuração:
Paths
Quando definimos os paths da nossa aplicação assim, podemos fazer import
com paths absolutos e não relativos dessa maneira:
Configuração:
Utilizando Husky
Podemos também utilizar o Husky para configurar scripts que vão verificar
se nosso código está com lint válido, se passa nos testes unitários, se não
possui erros de código.
Com Husky conseguimos criar scripts, que antes de um commit ou um push
roda outros scripts para verificar se o código, está no padrão esperado.
Também conseguimos configurar o Husky para aceitar apenas um padrão de
mensagens de commit, junto com packages como commitizen ou
commitlint, o que pode facilitar muito o log da nossa aplicação.
Configuração:
Gerando Releases
Depois de configurar como nosso projeto e tratar os paths da aplicação,
como ele valida o código antes de comitarmos, um terceiro passo é controlar
como geramos os releases do projeto.
Os releases podem ser gerados semanalmente,mensalmente, ou
diariamente tudo depende de como a equipe se organiza e qual a prioridade
de features,bugs,hotfix, etc.. que a equipe quer enviar para produção.
Utilizando o package semantic-release, podemos gerar CHANGELOGS
automáticos a cada versão de release.
Um exemplo de estrutura de projeto
.
Aqui um exemplo ao lado de estrutura que pode ser escalável sem bem
utilizada: (mais a frente vamos explicar as principais pastas)
assets: Pasta para assets como imagens,svgs, js terceiros
components: Pasta para os componentes do projeto
core: Pasta onde a lógica principal de funcionamento da aplicação fica
pages: A pasta com as páginas finais das rotas renderizadas.
tests: pasta para testes unitários, simula a estrutura da pasta src, para
organizar os testes por tipos de arquivo.
Um exemplo de estrutura de projeto:
Components
.
Categorizei esse exemplo de uma pasta components:
elements: Pasta com os componentes mais básicos do DOM da sua
aplicação e que vão ser re-utilizados por diversas vezes.
layout: Componentes globais de layout como footer,header,menus.
pages: componentes de página, aqui as páginas são construídas, tem sua
lógica e componentes específicos de cada página
templates: pasta para componentes de templates/temas específicos que
podem ser utilizados em diversas situações/tipos de
usuário/localidades/línguas
widgets: Elementos maiores compostos de vários elementos, mas que não
são únicos de uma página
Um exemplo de estrutura de projeto:
core
.
Na pasta core:
config: variavéis e objetos de configuração do projeto, como os Routes da
aplicação
context: Contexts da aplicação
helpers: Funcões que retornem uma formatação, validações, cálculos
hooks: Hooks da aplicação
middleware: Caso nossa aplicação utilize algum middleware
services: Os serviços da nossa aplicação
types: Onde armazenamos os tipos e interfaces da aplicação
Monitorando o projeto
Depois que temos o projeto está em produção, é bom monitorar alguns fatores como:
Erros no código: Sentry, é uma ferramenta de monitoramento de erros, que aceita diversas plataformas e
tecnologias.
Segurança: Existem ferramentas que pegam falhas de segurança como Sqreen e LGTM
Performance e Usuário: LightHouse & SpeedCurve, com essas duas ferramentas conseguimos monitorar
fatores importantes como tempo de carregamento de uma página, quantos usuários abandonam a página
sem navegar pelo resto do projeto, qual a velocidade
SonarQube: Na plataforma do SonarCloud.com você consegue linkar com seu projeto no github, e pegar
parametros como Manutenibilidade de código, Coverage de testes, code smells, duplicação de código etc.
Testes
Quando pensamos em escalar uma aplicação uma forma de evitar que ela quebre, e que se comporte como
esperamos trabalhamos com testes:
Testes Unitários: O recomendado é fazer testes unitários em todos serviços e pelo menos nos componentes
principais da aplicação e que lidam com dados sensíveis do usuário.
Com TypeScript conseguimos usar nossos tipos e interfaces para fazer mocks de respostas de serviços. No
React utilizamos React Testing Library para testar componente visuais e Jest para testar funções e serviços.
Testes de Integração: Usamos os testes de Integração para verificar se a renderização de componentes, ou
integração de serviços está ocorrendo de forma como esperada.
Testes E2E: Os Testes E2E são importantes para garantir que o comportamento em nossa aplicação vai ser o
esperado. Utilizamos essa técnica para verificar se o fluxo que desejamos está ocorrendo como deveria.
Cypress é a lib mais utilizada do mercado.
Porque utilizar React em
aplicações Front-end escaláveis?
1 - Ótima documentação, muitos recursos de aprendizado,
Framework com maior base de conhecimento disponível na
internet
2 - Lib mais utilizada do mercado.
3 - React foi implementado em apps com alto volume de
dados e tráfego. O mais conhecido deles sendo o
Facebook,criador do React, mas também os maiores
e-commerces, portais, redes sociais ,e plataformas utilizam
React.
4 - Baixa curva de aprendizado
Porque utilizar TypeScript em
aplicações Front-end escaláveis?
1 - TypeScript torna fácil o entendimento do tipo de dados e
objetos de uma API, ou de uma aplicação
2 - Garante a consistência dos dados, evitando exceções e
erros.
3 - Impoem um guia de código
4 - Ajuda na arquitetura e estruturação do código
5 - Melhora a documentação e velocidade de entrega do
projeto
6 - Checagem de erros em tempo de compilação
7 - Ferramentas de debug nativas no VSCode
Porque utilizar
React + TypeScript?
React + TypeScript
https://www.npmtrends.com/@types/react-vs-flow-parser-vs-kotlin-react-vs-prop-types-vs-reason-react-vs-typescript-
vs-@jetbrains/kotlin-react
React + TypeScript
1 - TypeScript + @types/react juntos tem mais de 35 milhões
de downloads diários.
2 - O package @types/react, tem mais downloads do que
qualquer outro package de tipagem para React.
3 - TypeScript tem uma comunidade maior e mais conteúdo
se comparado a seus concorrentes.
4 - PropTypes que vem em segundo lugar nos packages para
tipagem de projetos React, teve sua última atualização em
Fevereiro de 2019.E apenas checa os tipos em Runtime.
5 - Flow que foi feito pelo Facebook, tem uma adoção muito
baixa e não chega a ser uma linguagem mas apenas um
checker de tipos estáticos.
Boas Práticas de React e TS
1 - Saiba que condicional usar
Em algumas situações operadores short
circuit && , podem retornar um valor 0 na sua
tela.
Isso é porque o React não trata o 0 como
falso, e para isso podemos usar um ternário
que é um pouco mais verboso, mas resolve
nosso problema, ou a dupla negação que
converte o 0 para false, e aí não renderiza o
0 na tela.
Boas Práticas de React e TS
2 - Use uma lib externa para Data Fetching
É sempre bom utilizar as Apis nativas do JavaScript como fetch, porém existem libs que
podem ser usadas no React como React Query ou SWR que utilizam Hooks para fazer essa
comunicação com o servidor.
Eles já vem com features prontas de Tratamento de Erros, Cacheamento, Hidratação de
componentes, Gerenciamento de Estados e etc. que se fossemos fazer do zero, iríamos
perder muito tempo reinventando a roda.
Caso trabalhe com APIS GraphQL, existem clientes como o Apollo, que já possui o
conceito de estado pronto.
Boas Práticas de React e TS
3 - Se o seu APP é grande o suficiente:
Use uma lib para gerenciar o estado
Em diversas situações o Context API nativo do React não vai funcionar como um gerenciador de estado da sua
aplicação.
Utilizar o Context API em situações como quando só precisamos passar dados de um componente para outro, ou
para compartilhar dados em baixo volume, é a solução ideal para o que precisamos
Mas em outras situações o Context API é apenas um injetor de dependências e não serve para tratar gerenciamento
de estados complexos, ou que sejam atualizados com alta frequência.
Para isso possuímos os Redux com Redux Toolkit, ou Mobx ou Recoil.
Escolher uma lib para gerenciar o estado da nossa aplicação pode ser uma decisão acertada, pois geralmente o
estado processa dados importantes da aplicação e se for arquitetado e manipulado de forma errada pode causar
grande perda de performance ou até quebrar nossa aplicação.
Boas Práticas de React e TS
4 - Não escreva código Hardcoded.
Utilize um objeto de config para isso
Um exemplo é esse código ao lado com um
arquivo de configuração de rotas.
Ele vai ser interpretado por um AppRoutes
que vai mapear cada objeto desse array e vai
renderizar uma rota da nossa aplicação
Boas Práticas de React e TS
4 - Não escreva código Hardcoded.
Utilize um objeto de config para isso
Ao lado temos o componente AppRoutes que possui
apenas a lógica de renderização das Rotas, não tendo
as rotas em si.
Separando a responsabilidade de cada componente,
um para os dados, e um para a interpretação dos
dados.
Boas Práticas de React e TS
5 - Faça a tipagem correta dos seus objetos/props e funções
Tipar nossos objetos com o tipo errado, ou com any, pode ocasionar problemas na hora de renderizar
nossa aplicação.
Especialmente em casos em que não fazemos nullcheck nos nossos dados.
um exemplo comum de componente com tipagem incorreta:
Boas Práticas de React e TS
5 - Faça a tipagem correta dos seus objetos/props
Qual o problema com o componente anterior?
1- Estamos usando any como tipo do prop data, aceitando qualquer valor que venha no componente.
2 - caso esse prop data seja nulo ou undefined, ele vai quebrar a renderização do componente.
3 - Não estamos forçando o tipo de retorno do nosso Componente. na teoria ele pode retornar qualquer coisa.
4 - Para isso corrigimos nosso componente dessa forma:
Boas Práticas de React e TS
5 - Faça a tipagem correta dos seus objetos/props
No exemplo do slide anterior, estamos especificando uma interface para a props
data, que recebemos no nosso componente, e que ele é um objeto de um array (por
isso fazemos map dele),
e antes de fazermos esse map, realizamos o nullcheck, pra saber se essa prop data
existe e não é nem null e nem undefined.
Caso seja retorna null e não quebra a nossa aplicação.
Boas Práticas de React e TS
6 - Centralize componentes externos
Caso você utilize componentes de outras libs e packages,é uma boa prática, você centralizar em uma pasta
shared todos os imports dos seus componentes, pois quando você importar nos seus componentes locais,
os mesmos não precisam saber da onde vem esses componentes externos.
Facilitando inclusive a troca de libs caso seja necessário.
Assim você tem apenas uma fonte de informação que é facilmente substituível, ao invés de ter que substituir
em sua aplicação inteira.
Boas Práticas de React e TS
7 - Utilize Hooks
Hooks veio para ajudar no re-uso de lógica e compartilhamento de estado entre componentes da nossa
aplicação.
Antes dos Hooks, a forma de fazer isso era através de High Order Components ou Render Props.
O ruim de usar HOC, é que os valores que precisamos vem dentro de props, que não temos uma idéia
clara se vem do componente pai, ou do componente que estamos adicionando no HOC.
com Hooks conseguimos separar a parte lógica do componente, e reutilizá la onde quisermos em nossa
aplicação.
Além de deixar nosso componente muito mais legível.
Boas Práticas de React e TS
8 - Preste Atenção nos Re-Renders:
useMemo() x useCallback()
Quando atualizamos as props de nosso componente ele causa re-render em todos sua estrutura,
seja o filho ou o próprio componente pai, inclusive em partes/estruturas do componente que não
foram atualizadas.
Para evitar isso existem dois Hooks que nos ajudam a não causar Re-renders desnecessários:
useMemo() x useCallback()
useMemo(), serve para guardamos valores em cache, e só atualizar quando o valor da dependência
que especificamos no hook mudar.
useCallBack(), serve para guardar um método em cache ,que só vai ser chamado/atualizado se as
suas dependências forem atualizadas.
A importância de utilizarmos esses Hooks, é especialmente porque ele evita muitos problemas de
performance para o usuário.
Boas Práticas de React e TS
9 - Utilize Object Literals ao invés de switch
Muitas vezes quando precisamos fazer algum código condicional como muitos if/else,utilizamos
switch/case, mas o problema do switch case é que ele não escala muito bem. Object literal é mais
simples. podemos por exemplo usar para instanciar um componente:
Boas Práticas de React e TS
9 - Utilize Object Literals ao invés de switch
Nesse exemplo, temos no slider anterior um Componente de Página que centraliza todos os componentes
de página, e que abstrai para outro componente a lógica e UI da página,e abaixo seria o componente
principal que apenas instancia esse componente centralizador com o "type" do componente de que
queremos.
Boas Práticas de React e TS
9 - Utilize Object Literals ao invés de switch
Qual a vantagem de usar essa abordagem para Componentes, lógica de código, casos de exceção etc?
Seu código fica mais organizado. Mais intuitivo. Caso você queira trocar um componente, remover, ou até
testar seu código ele fica muito mais simples para atingir esses resultados.
E escalavel.
Porque nesse exemplo anterior, sabemos onde está sendo instanciado todos nossos componentes de
páginas, e assim podemos a partir do Object Literal instanciar mais componentes, que separando a parte
lógica de um componente de Rota ( como o do slider anterior ), podemos não só organizar melhor nosso
código, mas re-utiliza-lo também.
Boas Práticas de React e TS
10 - Abstraia Serviços
Uma boa prática para tornar sua
aplicação escalável, é ter uma função
que retorna os mesmos tipos de
componentes, ou serviços por exemplo.
Vamos dar um exemplo de abstração de
um serviço:
Primeiro criamos um serviço genérico de
Fetch que vai ser utilizado em todos os
nossos serviços:
10 - Abstraia Serviços
No nosso serviço específico de busca de
artigos, apenas passamos o parâmetro
da URL que queremos para nosso serviço
de fetch genérico.
Boas Práticas de React e TS
10 - Abstraia Serviços
agora podemos fazer um import mais limpo e usar nosso serviço dessa maneira:
Boas Práticas de React e TS
10 - Abstraia Serviços
Encapsulando nosso serviços em um só lugar, fica mais fácil de substituir eles depois:
Boas Práticas de React e TS
O que é SOLID?
SOLID é um acronimo para 5 principios
de software que tem como objetivo
definir práticas que mantém o software
mais intuitivo, flexível e manutenível.
Conceitos de SOLID para React
SOLID , um conceito muito difundido na programação orientada a objetos pode ser usada
em programação funcional? vamos ver o que o Uncle Bob tem a dizer sobre isso:
Tweet traduzido de: https://twitter.com/unclebobmartin/status/1164511654618550273
Quais são os conceitos Solid?
S de Single Responsibility Principle:
Um Componente ou função só deve fazer uma
coisa e fazê-la direito.
Um componente comum em projetos React:
Aqui um componente de listagem de gatos: ( continua no próximo slide)
Single Responsibility Principle no React/TS
Qual o problema com esse componente? Vamos lá:
1 - Ele define um estado inicial
2 - Depois ele define uma função redutora para gerenciar esse estado
3 - Ele define uma interface que vai ser o tipo principal do objeto que é a
razão desse componente
4 - Ele define um Componente, que faz 1 - Um serviço de chamada de API e
uma filtragem desse resultado de API
5- Ele instância esse objeto resultado da chamada da API, e então retorna os
dados dentro de um componente HTML.
Single Responsibility Principle no React/TS
Como resolver os problemas definidos no slide anterior
respeitando o princípio de Single Responsibility?
1 - Podemos abstrair o código do useReducer() para uma função
redutora separada para tratar o state da nossa função.
2 - Podemos abstrair o código dos hooks useEffect:
1 - passando o fetch para um serviço genérico HTTP.
2 - Criando um hook específico para lidar com a resposta desse
serviço e fazer o filtro que esperamos do objeto. ex: useCatHook()
3 - o hook useCatHook(), voltaria 2 propriedades , a resposta = cats, e o
isLoading para trazer se a resposta já foi obtida ou não.
4 - Fariamos um componente UI, que faria um map no objeto cats e
imprimiria nossa lista com dados dos gatos.
3 - No final iriamos só renderizar o componente final que organiza toda
a lógica que precisamos para renderizar a lista de gatos :)
Open Closed Principle no React/TS
“Robert C. Martin (Uncle Bob) considerou este princípio como o‘ princípio mais importante do design
orientado a objetos ’.
Mas ele não foi o primeiro a defini-lo. Bertrand Meyer escreveu sobre isso em 1988 em seu livro
Object-Oriented Software Construction.
Ele explicou o princípio Open/Closed como:
‘Entidades de software (classes, módulos, funções, etc.) devem ser abertas para extensão, mas fechadas
para modificação.’ ”
Open Closed Principle no React/TS
Usando Open / Closed Principle:
Assim como já demonstramos com a Abstração de Serviços e Object Literals, no componente abaixo mostramos
mais um exemplo de Open Closed Principle, onde não importa quantos tipos de gato podemos criar, não alteramos
o código do componente de gatos principal.
Open Closed Principle no React/TS
Liskov Substitution Principle no React/TS
O princípio de Liskov Substitution nos diz que:
“Os componentes devem obedecer a
algum tipo de contrato.”
Basicamente, isso significa que deve haver algum tipo de contrato entre os componentes. Portanto, sempre que um
componente usa outro componente, ele não deve interromper sua funcionalidade (ou criar algum efeito colateral
indesejado).
Liskov Substitution Principle no React/TS
Imagine que temos um componente que recebe um dado
via props e passa para seu componente filho:
E aí renderizamos esse componente no nosso App,
passando um objeto key: "value"
Liskov Substitution Principle no React/TS
Eis que estoura um erro no console
Então TypeScript vem para nos salvar!
Quando tipamos o prop data do nosso
componente estamos atribuindo a ele um
tipo único que caso não seja obedecido, vai
estourar um erro no nosso Vs Code:
Liskov Substitution Principle no React/TS
Agora quando tentamos renderizar nosso componente em
outro, ele vai acusar erro, caso não respeitamos o
contrato entre componentes:
Liskov Substitution Principle no React/TS
Se substituirmos a propriedade do objeto pela
propriedade correta, ele para de acusar o Erro e
conseguimos respeitar o princípio de Liskov Substitution
Interface Segregation Principle no React/TS
O princípio de Interface Segragation nos diz que:
“Os componentes não devem depender
de coisas de que não precisam.”
Interface Segregation Principle no React/TS
Imagine que temos nosso componente de gatos pai, que renderiza um Componente com detalhes do gato, e um com
imagens do gato, e em ambos passamos nosso objeto cat:
Interface Segregation Principle no React/TS
Qual o problema com o código do slide anterior?
1 - Ele está passando props desnecessárias para nossos componentes filhos, esse tipo de situação
é muito comum quando retornamos a resposta de uma API sem tratar os dados devidos, ou não
tipos e passamos os parâmetros certos para nossos componentes
2- Basta passar o objeto correto para nossos componentes filhos e então não violamos mais o
princípio de Interface Segregation.
Dependency Inversion Principle no React/TS
O princípio de Dependency Inversion nos diz que:
“Nenhum componente ou função deve se preocupar com a forma como
uma determinada coisa é feita.”
Dependency Inversion Principle no React/TS
Imaginamos que temos um componente que precise fazer o fetch de dados de uma base de
cachorros como no código abaixo:
Dependency Inversion Principle no React/TS
Qual o problema desse código?
1 - Ele Depende de alguns dados remotos que são buscados diretamente no componente.
2- A principal responsabilidade do nosso componente Dogs é processar e renderizar os dados.
3 - Ele não deve se preocupar com a forma como os dados são buscados ou de onde os dados
vêm.
Este componente sabe demais - e isso é um problema.
Imagine que:
1 - Você precise fazer fetch de dados em mais de 50 componentes.
2 - Seu chefe resolve trocar fetch, por axios por exemplo, e você tenha que trocar nos 50
componentes.
3 - Depois ele pede que você faça o cacheamento dos dados.
Dependency Inversion Principle no React/TS
Como arrumar meu código para não ferir o princípio de Dependency Inversion?
1 - Podemos abstrair toda lógica de fetch de dados para um hook customizável: useFetch() hook
por exemplo.
2- Nesse hook podemos usar o axios ou lib que quisermos além de implementar o cacheamento
dos dados.
3 - Assim não precisamos implementar o mesmo código em mais de 50 componentes, evitando a
possibilidade de criar Bugs desnecessários, economizando tempo e manutenção.
Como sei se estou quebrando o princípio de Dependency Inversion?
1 - Na maioria dos casos se você está quebrando o princípio de Single Responsibility, você
também está quebrando o princípio de Dependency Inversion.
2 - Olhe nos imports do seu componente. Se você não está importando apenas componentes
que são responsáveis por renderização no UI (um Modal por Exemplo), você pode estar violando
o princípio de Dependency Inversion.
Contatos:
ruben@rubenmarcus.dev
github.com/rubenmarcus
linkedin.com/in/rubenmarcus
dev.to/rubenmarcus
rubenmarcus.medium.com
Obrigado!

Contenu connexe

Tendances

Refactoring Applications using SOLID Principles
Refactoring Applications using SOLID PrinciplesRefactoring Applications using SOLID Principles
Refactoring Applications using SOLID PrinciplesSteven Smith
 
Mikrofrontend a Module Federation
Mikrofrontend a Module FederationMikrofrontend a Module Federation
Mikrofrontend a Module FederationThe Software House
 
Domain driven design
Domain driven designDomain driven design
Domain driven designtatyaso
 
Introduction to Spring Framework
Introduction to Spring FrameworkIntroduction to Spring Framework
Introduction to Spring FrameworkHùng Nguyễn Huy
 
Microservices
MicroservicesMicroservices
MicroservicesSmartBear
 
Monolith to Microservices - O’Reilly Oscon
Monolith to Microservices - O’Reilly OsconMonolith to Microservices - O’Reilly Oscon
Monolith to Microservices - O’Reilly OsconChristopher Grant
 
Clean architecture
Clean architectureClean architecture
Clean architecture.NET Crowd
 
Easy Microservices with JHipster - Devoxx BE 2017
Easy Microservices with JHipster - Devoxx BE 2017Easy Microservices with JHipster - Devoxx BE 2017
Easy Microservices with JHipster - Devoxx BE 2017Deepu K Sasidharan
 
Introducing DevOps, IT Sharing Session 20 Nov 2017
Introducing DevOps, IT Sharing Session 20 Nov 2017Introducing DevOps, IT Sharing Session 20 Nov 2017
Introducing DevOps, IT Sharing Session 20 Nov 2017Danny Ariwicaksono
 
Rest API with Swagger and NodeJS
Rest API with Swagger and NodeJSRest API with Swagger and NodeJS
Rest API with Swagger and NodeJSLuigi Saetta
 

Tendances (20)

Dot Net Core
Dot Net CoreDot Net Core
Dot Net Core
 
Refactoring Applications using SOLID Principles
Refactoring Applications using SOLID PrinciplesRefactoring Applications using SOLID Principles
Refactoring Applications using SOLID Principles
 
Mikrofrontend a Module Federation
Mikrofrontend a Module FederationMikrofrontend a Module Federation
Mikrofrontend a Module Federation
 
Domain driven design
Domain driven designDomain driven design
Domain driven design
 
Benefits of developing single page web applications using angular js
Benefits of developing single page web applications using angular jsBenefits of developing single page web applications using angular js
Benefits of developing single page web applications using angular js
 
Introduction to Spring Framework
Introduction to Spring FrameworkIntroduction to Spring Framework
Introduction to Spring Framework
 
Next.js - ReactPlayIO.pptx
Next.js - ReactPlayIO.pptxNext.js - ReactPlayIO.pptx
Next.js - ReactPlayIO.pptx
 
DevOps
DevOpsDevOps
DevOps
 
Microservices
MicroservicesMicroservices
Microservices
 
Introduction to DevOps
Introduction to DevOpsIntroduction to DevOps
Introduction to DevOps
 
Monolith to Microservices - O’Reilly Oscon
Monolith to Microservices - O’Reilly OsconMonolith to Microservices - O’Reilly Oscon
Monolith to Microservices - O’Reilly Oscon
 
DevOps introduction
DevOps introductionDevOps introduction
DevOps introduction
 
Micro-frontends – is it a new normal?
Micro-frontends – is it a new normal?Micro-frontends – is it a new normal?
Micro-frontends – is it a new normal?
 
Clean architecture
Clean architectureClean architecture
Clean architecture
 
REST vs SOAP
REST vs SOAPREST vs SOAP
REST vs SOAP
 
Introduction to DevOps
Introduction to DevOpsIntroduction to DevOps
Introduction to DevOps
 
O que é DevOps afinal?
O que é DevOps afinal?O que é DevOps afinal?
O que é DevOps afinal?
 
Easy Microservices with JHipster - Devoxx BE 2017
Easy Microservices with JHipster - Devoxx BE 2017Easy Microservices with JHipster - Devoxx BE 2017
Easy Microservices with JHipster - Devoxx BE 2017
 
Introducing DevOps, IT Sharing Session 20 Nov 2017
Introducing DevOps, IT Sharing Session 20 Nov 2017Introducing DevOps, IT Sharing Session 20 Nov 2017
Introducing DevOps, IT Sharing Session 20 Nov 2017
 
Rest API with Swagger and NodeJS
Rest API with Swagger and NodeJSRest API with Swagger and NodeJS
Rest API with Swagger and NodeJS
 

Similaire à Escalando apps com React e Type Script e SOLID

Tendências e Dicas para o Desenvolvimento de Software
Tendências e Dicas para o Desenvolvimento de SoftwareTendências e Dicas para o Desenvolvimento de Software
Tendências e Dicas para o Desenvolvimento de SoftwareNorberto Santos
 
Testes automatizados.pptx
Testes automatizados.pptxTestes automatizados.pptx
Testes automatizados.pptxCarlos Gonzaga
 
Projeto Indiana
Projeto IndianaProjeto Indiana
Projeto Indianahellequin
 
Infraestrutura como código Terraform aws openshift Ansible
Infraestrutura como código Terraform aws openshift AnsibleInfraestrutura como código Terraform aws openshift Ansible
Infraestrutura como código Terraform aws openshift AnsibleClaudemir de Almeida Rosa
 
Ferramenta de Cloud Computer para apoio à Engenharia de Software
Ferramenta de Cloud Computer para apoio à Engenharia de SoftwareFerramenta de Cloud Computer para apoio à Engenharia de Software
Ferramenta de Cloud Computer para apoio à Engenharia de SoftwareDanilo Sousa
 
TDC2018SP | Trilha Arq .Net - 12-factor apps: Boas praticas na construcao de ...
TDC2018SP | Trilha Arq .Net - 12-factor apps: Boas praticas na construcao de ...TDC2018SP | Trilha Arq .Net - 12-factor apps: Boas praticas na construcao de ...
TDC2018SP | Trilha Arq .Net - 12-factor apps: Boas praticas na construcao de ...tdc-globalcode
 
12 Factor App TDC São Paulo 2018
12 Factor App TDC São Paulo 201812 Factor App TDC São Paulo 2018
12 Factor App TDC São Paulo 2018Graziella Bonizi
 
Web Tools Pt B R
Web Tools Pt  B RWeb Tools Pt  B R
Web Tools Pt B Rguestb9d145
 
Academia do Arquiteto - Implantando A.L.M. em uma semana!
Academia do Arquiteto - Implantando A.L.M. em uma semana!Academia do Arquiteto - Implantando A.L.M. em uma semana!
Academia do Arquiteto - Implantando A.L.M. em uma semana!Globalcode
 
Como DDD e Strategic Design estão nos ajudando a modernizar um Legado
Como DDD e Strategic Design estão nos ajudando a modernizar um LegadoComo DDD e Strategic Design estão nos ajudando a modernizar um Legado
Como DDD e Strategic Design estão nos ajudando a modernizar um LegadoLuiz Costa
 
TDC2016SP - Revitalizando aplicações desktop usando CefGlue, MessageBus e Rea...
TDC2016SP - Revitalizando aplicações desktop usando CefGlue, MessageBus e Rea...TDC2016SP - Revitalizando aplicações desktop usando CefGlue, MessageBus e Rea...
TDC2016SP - Revitalizando aplicações desktop usando CefGlue, MessageBus e Rea...tdc-globalcode
 
ALM Open Source Ponta a Ponta - Minicurso Globalcode MC-122
ALM Open Source Ponta a Ponta - Minicurso Globalcode MC-122ALM Open Source Ponta a Ponta - Minicurso Globalcode MC-122
ALM Open Source Ponta a Ponta - Minicurso Globalcode MC-122Bruno Souza
 
Apresentação Minas - Desenvolvendo Sites
Apresentação Minas - Desenvolvendo SitesApresentação Minas - Desenvolvendo Sites
Apresentação Minas - Desenvolvendo Sitesthiagolima
 
Trabalho 4 Semestre e 5 Semestre 2015
Trabalho 4 Semestre e 5 Semestre 2015Trabalho 4 Semestre e 5 Semestre 2015
Trabalho 4 Semestre e 5 Semestre 2015Rodrigo Marinho
 
Docker + Bancos de Dados: descomplicando a montagem de ambientes de Desenvolv...
Docker + Bancos de Dados: descomplicando a montagem de ambientes de Desenvolv...Docker + Bancos de Dados: descomplicando a montagem de ambientes de Desenvolv...
Docker + Bancos de Dados: descomplicando a montagem de ambientes de Desenvolv...Renato Groff
 
TDC2016POA | Trilha Arquetetura - Revitalizando aplicações desktop usando Ce...
TDC2016POA | Trilha Arquetetura -  Revitalizando aplicações desktop usando Ce...TDC2016POA | Trilha Arquetetura -  Revitalizando aplicações desktop usando Ce...
TDC2016POA | Trilha Arquetetura - Revitalizando aplicações desktop usando Ce...tdc-globalcode
 
TDC2016SP Trilha Arquitetura.NET - Revitalizando aplicações desktop usando C...
TDC2016SP  Trilha Arquitetura.NET - Revitalizando aplicações desktop usando C...TDC2016SP  Trilha Arquitetura.NET - Revitalizando aplicações desktop usando C...
TDC2016SP Trilha Arquitetura.NET - Revitalizando aplicações desktop usando C...Marcelo Palladino
 

Similaire à Escalando apps com React e Type Script e SOLID (20)

Tendências e Dicas para o Desenvolvimento de Software
Tendências e Dicas para o Desenvolvimento de SoftwareTendências e Dicas para o Desenvolvimento de Software
Tendências e Dicas para o Desenvolvimento de Software
 
Testes automatizados.pptx
Testes automatizados.pptxTestes automatizados.pptx
Testes automatizados.pptx
 
Projeto Indiana
Projeto IndianaProjeto Indiana
Projeto Indiana
 
Infraestrutura como código Terraform aws openshift Ansible
Infraestrutura como código Terraform aws openshift AnsibleInfraestrutura como código Terraform aws openshift Ansible
Infraestrutura como código Terraform aws openshift Ansible
 
Ferramenta de Cloud Computer para apoio à Engenharia de Software
Ferramenta de Cloud Computer para apoio à Engenharia de SoftwareFerramenta de Cloud Computer para apoio à Engenharia de Software
Ferramenta de Cloud Computer para apoio à Engenharia de Software
 
TDC2018SP | Trilha Arq .Net - 12-factor apps: Boas praticas na construcao de ...
TDC2018SP | Trilha Arq .Net - 12-factor apps: Boas praticas na construcao de ...TDC2018SP | Trilha Arq .Net - 12-factor apps: Boas praticas na construcao de ...
TDC2018SP | Trilha Arq .Net - 12-factor apps: Boas praticas na construcao de ...
 
12 Factor App TDC São Paulo 2018
12 Factor App TDC São Paulo 201812 Factor App TDC São Paulo 2018
12 Factor App TDC São Paulo 2018
 
PHP 10 CodeIgniter
PHP 10 CodeIgniterPHP 10 CodeIgniter
PHP 10 CodeIgniter
 
Web Tools Pt B R
Web Tools Pt  B RWeb Tools Pt  B R
Web Tools Pt B R
 
A Linguagem Php
A Linguagem PhpA Linguagem Php
A Linguagem Php
 
Academia do Arquiteto - Implantando A.L.M. em uma semana!
Academia do Arquiteto - Implantando A.L.M. em uma semana!Academia do Arquiteto - Implantando A.L.M. em uma semana!
Academia do Arquiteto - Implantando A.L.M. em uma semana!
 
Como DDD e Strategic Design estão nos ajudando a modernizar um Legado
Como DDD e Strategic Design estão nos ajudando a modernizar um LegadoComo DDD e Strategic Design estão nos ajudando a modernizar um Legado
Como DDD e Strategic Design estão nos ajudando a modernizar um Legado
 
TDC2016SP - Revitalizando aplicações desktop usando CefGlue, MessageBus e Rea...
TDC2016SP - Revitalizando aplicações desktop usando CefGlue, MessageBus e Rea...TDC2016SP - Revitalizando aplicações desktop usando CefGlue, MessageBus e Rea...
TDC2016SP - Revitalizando aplicações desktop usando CefGlue, MessageBus e Rea...
 
ALM Open Source Ponta a Ponta - Minicurso Globalcode MC-122
ALM Open Source Ponta a Ponta - Minicurso Globalcode MC-122ALM Open Source Ponta a Ponta - Minicurso Globalcode MC-122
ALM Open Source Ponta a Ponta - Minicurso Globalcode MC-122
 
Apresentação Minas - Desenvolvendo Sites
Apresentação Minas - Desenvolvendo SitesApresentação Minas - Desenvolvendo Sites
Apresentação Minas - Desenvolvendo Sites
 
Trabalho 4 Semestre e 5 Semestre 2015
Trabalho 4 Semestre e 5 Semestre 2015Trabalho 4 Semestre e 5 Semestre 2015
Trabalho 4 Semestre e 5 Semestre 2015
 
Docker + Bancos de Dados: descomplicando a montagem de ambientes de Desenvolv...
Docker + Bancos de Dados: descomplicando a montagem de ambientes de Desenvolv...Docker + Bancos de Dados: descomplicando a montagem de ambientes de Desenvolv...
Docker + Bancos de Dados: descomplicando a montagem de ambientes de Desenvolv...
 
TDC2016POA | Trilha Arquetetura - Revitalizando aplicações desktop usando Ce...
TDC2016POA | Trilha Arquetetura -  Revitalizando aplicações desktop usando Ce...TDC2016POA | Trilha Arquetetura -  Revitalizando aplicações desktop usando Ce...
TDC2016POA | Trilha Arquetetura - Revitalizando aplicações desktop usando Ce...
 
TDC2016SP Trilha Arquitetura.NET - Revitalizando aplicações desktop usando C...
TDC2016SP  Trilha Arquitetura.NET - Revitalizando aplicações desktop usando C...TDC2016SP  Trilha Arquitetura.NET - Revitalizando aplicações desktop usando C...
TDC2016SP Trilha Arquitetura.NET - Revitalizando aplicações desktop usando C...
 
Ruby on Rails for beginners 2.0
Ruby on Rails for beginners 2.0Ruby on Rails for beginners 2.0
Ruby on Rails for beginners 2.0
 

Escalando apps com React e Type Script e SOLID

  • 1. Escalando Apps com React e TypeScript por Ruben Marcus
  • 2. Um pouco sobre mim ● Atuo 10 anos com Desenvolvimento Web ● Atuo com React desde 2016. Com Next.js e TypeScript desde 2018. ● Já atuei em Portais e E-commerces com milhões de visitas diárias ● Atuo com foco em melhoria de código e performance de aplicações ● 31k pessoas leram minhas respostas no Stack Overflow ● 35k de leituras nos artigos do Medium e dev.to ● Já Atuei em Projetos de 5 Países, com pessoas de mais de 70 países.
  • 3. O que você vai ver nessa apresentação ▪ Quem deve Escalar? ▪ O que é Escalabilidade? ▪ Problemas Comuns ▪ Desafios ▪ Mantenabilidade Escalabilidade 01. ▪ GIT ▪ Configurando um projeto ▪ Estrutura de Projetos ▪ Monitoramento ▪ Testes Arquitetura 02. ▪ React + TS ▪ Boas Práticas de React e TypeScript ▪ Solid com React e TypeScript React + TS 03.
  • 4. Quem deve pensar em Escalar? Qualquer pessoa que queira atuar em um projeto que tenha um crescimento muito rápido em sua base de código, e uma alta frequência de atualização de seus co-criadores.
  • 5. Quais problemas evitamos em um projeto escalável? - Custos de Infraestrutura. - Alta curva de aprendizado de novos integrantes - Performance - Manutenabilidade - Falta de Agilidade e Problemas de Entrega de novas features
  • 6. Como sabemos que um projeto é escalável? - O projeto consegue aumentar recursos de infra-estrutura sem aumentar absurdamente os custos - Estrutura do Projeto é simples e intuitiva - Complexidade e Número de dependências não impede o crescimento do projeto - Aprendizado sobre o produto e base de código de novos integrantes ocorre de forma orgânica e sem maiores dificuldades - Projeto raramente têm bloqueios na parte técnica - Projeto consegue atender uma base de usuários enorme, sem maiores problemas. - Projeto necessita de poucas refatorações para ser o mais performático possível
  • 7. Problemas comuns de Escalabilidade - Cada Desenvolvedor quer implementar seu estilo de código ou paradigma de programação ( Programação Funcional x POO) - Mudanças frequentes na estrutura de projeto ou estilo de código (ex: JSX para TSX - Complexidade e Número de dependências que impede o crescimento do projeto - Código que fere o princípio de Single Responsibility, e que se alterado pode quebrar muitas partes do projeto. - Código sem nenhuma documentação - As Pessoas que fizeram a maior parte do projeto e tinham conhecimento sobre ele, já deixaram a equipe. - Projeto engessado com dependências muito antigas (ex: só compativel com IE)
  • 8. Você define a cada decisão se seu projeto vai ser escalável ou não
  • 9. Como saber se meu código é escalavel? Faça a si mesmo as seguintes perguntas: - Meu código é legível, de fácil entendimento, performático (faz mais com menos código), tem vazamento de memória? - Já existe algum componente, função, método, serviço na aplicação que faz o que quero fazer? - Essa é a melhor forma de criar a estrutura de arquivos do meu código? - Os custos para o navegador, usuário e servidor são grandes demais? - Meu código implementa alguma melhoria, ou introduz bugs? - O tipo de dados e objetos são coerentes com o fluxo da aplicação e não existe a possibilidade de quebrar a mesma? - Só eu entendo a lógica escrita? - Consigo explicar esse código facilmente para qualquer novato na equipe?
  • 10. Arquitetura: Estruturando seu projeto Existem diversas formas de estruturar um projeto React. Você pode utilizar Atomic Design para fazer um projeto escalável. Como pode utilizar uma estrutura de pastas muito semelhante ao CRA ( Create React App ). Mas caso sua aplicação esteja ficando muito complexa, ou com Componentes globais demais, talvez seja o momento de adotar uma arquitetura Micro-frontend. Ou criar uma lib para seus componentes de layout. Ou dividir sua pasta em mais subpastas.
  • 11. Arquitetura: Estruturando seu projeto Você pode descobrir se a arquitetura do seu projeto está ruim, se para renderizar um componente em uma página, você depende de um número muito grande de arquivos e dependências para isso. O contrário também é válido, ter um componente gigantesco de mais de 1000 linhas, em que o código fique gigantesco e difícil de debugar, é um problema bem grande para escalabilidade.
  • 12. Arquitetura: GIT Na hora de decidir como sua equipe vai atuar em um projeto, pode-se usar tanto um repositório por projeto, como mono-repos. Dependendo do tamanho do seu projeto, mono-repos não é uma solução viável, devido a performance baixa do Git para lidar com projetos grandes em monorepos, e a problemas de segurança que um projeto pode estar exposto ao estar em um mono-repo. Como padrão de branches,recomendo o Gitflow. Como padrão de commits, recomendo usar Conventional Commits. Para fazer releases: Semantic Release.
  • 13. Configuração: Paths Quando estamos configurando um Projeto React + TS, algumas práticas que considero vitais para que um app seja escalável: - Configurar os paths no arquivo tsconfig.json, por exemplo:
  • 14. Configuração: Paths Quando definimos os paths da nossa aplicação assim, podemos fazer import com paths absolutos e não relativos dessa maneira:
  • 15. Configuração: Utilizando Husky Podemos também utilizar o Husky para configurar scripts que vão verificar se nosso código está com lint válido, se passa nos testes unitários, se não possui erros de código. Com Husky conseguimos criar scripts, que antes de um commit ou um push roda outros scripts para verificar se o código, está no padrão esperado. Também conseguimos configurar o Husky para aceitar apenas um padrão de mensagens de commit, junto com packages como commitizen ou commitlint, o que pode facilitar muito o log da nossa aplicação.
  • 16. Configuração: Gerando Releases Depois de configurar como nosso projeto e tratar os paths da aplicação, como ele valida o código antes de comitarmos, um terceiro passo é controlar como geramos os releases do projeto. Os releases podem ser gerados semanalmente,mensalmente, ou diariamente tudo depende de como a equipe se organiza e qual a prioridade de features,bugs,hotfix, etc.. que a equipe quer enviar para produção. Utilizando o package semantic-release, podemos gerar CHANGELOGS automáticos a cada versão de release.
  • 17. Um exemplo de estrutura de projeto . Aqui um exemplo ao lado de estrutura que pode ser escalável sem bem utilizada: (mais a frente vamos explicar as principais pastas) assets: Pasta para assets como imagens,svgs, js terceiros components: Pasta para os componentes do projeto core: Pasta onde a lógica principal de funcionamento da aplicação fica pages: A pasta com as páginas finais das rotas renderizadas. tests: pasta para testes unitários, simula a estrutura da pasta src, para organizar os testes por tipos de arquivo.
  • 18. Um exemplo de estrutura de projeto: Components . Categorizei esse exemplo de uma pasta components: elements: Pasta com os componentes mais básicos do DOM da sua aplicação e que vão ser re-utilizados por diversas vezes. layout: Componentes globais de layout como footer,header,menus. pages: componentes de página, aqui as páginas são construídas, tem sua lógica e componentes específicos de cada página templates: pasta para componentes de templates/temas específicos que podem ser utilizados em diversas situações/tipos de usuário/localidades/línguas widgets: Elementos maiores compostos de vários elementos, mas que não são únicos de uma página
  • 19. Um exemplo de estrutura de projeto: core . Na pasta core: config: variavéis e objetos de configuração do projeto, como os Routes da aplicação context: Contexts da aplicação helpers: Funcões que retornem uma formatação, validações, cálculos hooks: Hooks da aplicação middleware: Caso nossa aplicação utilize algum middleware services: Os serviços da nossa aplicação types: Onde armazenamos os tipos e interfaces da aplicação
  • 20. Monitorando o projeto Depois que temos o projeto está em produção, é bom monitorar alguns fatores como: Erros no código: Sentry, é uma ferramenta de monitoramento de erros, que aceita diversas plataformas e tecnologias. Segurança: Existem ferramentas que pegam falhas de segurança como Sqreen e LGTM Performance e Usuário: LightHouse & SpeedCurve, com essas duas ferramentas conseguimos monitorar fatores importantes como tempo de carregamento de uma página, quantos usuários abandonam a página sem navegar pelo resto do projeto, qual a velocidade SonarQube: Na plataforma do SonarCloud.com você consegue linkar com seu projeto no github, e pegar parametros como Manutenibilidade de código, Coverage de testes, code smells, duplicação de código etc.
  • 21. Testes Quando pensamos em escalar uma aplicação uma forma de evitar que ela quebre, e que se comporte como esperamos trabalhamos com testes: Testes Unitários: O recomendado é fazer testes unitários em todos serviços e pelo menos nos componentes principais da aplicação e que lidam com dados sensíveis do usuário. Com TypeScript conseguimos usar nossos tipos e interfaces para fazer mocks de respostas de serviços. No React utilizamos React Testing Library para testar componente visuais e Jest para testar funções e serviços. Testes de Integração: Usamos os testes de Integração para verificar se a renderização de componentes, ou integração de serviços está ocorrendo de forma como esperada. Testes E2E: Os Testes E2E são importantes para garantir que o comportamento em nossa aplicação vai ser o esperado. Utilizamos essa técnica para verificar se o fluxo que desejamos está ocorrendo como deveria. Cypress é a lib mais utilizada do mercado.
  • 22. Porque utilizar React em aplicações Front-end escaláveis?
  • 23. 1 - Ótima documentação, muitos recursos de aprendizado, Framework com maior base de conhecimento disponível na internet 2 - Lib mais utilizada do mercado. 3 - React foi implementado em apps com alto volume de dados e tráfego. O mais conhecido deles sendo o Facebook,criador do React, mas também os maiores e-commerces, portais, redes sociais ,e plataformas utilizam React. 4 - Baixa curva de aprendizado
  • 24. Porque utilizar TypeScript em aplicações Front-end escaláveis?
  • 25. 1 - TypeScript torna fácil o entendimento do tipo de dados e objetos de uma API, ou de uma aplicação 2 - Garante a consistência dos dados, evitando exceções e erros. 3 - Impoem um guia de código 4 - Ajuda na arquitetura e estruturação do código 5 - Melhora a documentação e velocidade de entrega do projeto 6 - Checagem de erros em tempo de compilação 7 - Ferramentas de debug nativas no VSCode
  • 26. Porque utilizar React + TypeScript?
  • 28. React + TypeScript 1 - TypeScript + @types/react juntos tem mais de 35 milhões de downloads diários. 2 - O package @types/react, tem mais downloads do que qualquer outro package de tipagem para React. 3 - TypeScript tem uma comunidade maior e mais conteúdo se comparado a seus concorrentes. 4 - PropTypes que vem em segundo lugar nos packages para tipagem de projetos React, teve sua última atualização em Fevereiro de 2019.E apenas checa os tipos em Runtime. 5 - Flow que foi feito pelo Facebook, tem uma adoção muito baixa e não chega a ser uma linguagem mas apenas um checker de tipos estáticos.
  • 29. Boas Práticas de React e TS 1 - Saiba que condicional usar Em algumas situações operadores short circuit && , podem retornar um valor 0 na sua tela. Isso é porque o React não trata o 0 como falso, e para isso podemos usar um ternário que é um pouco mais verboso, mas resolve nosso problema, ou a dupla negação que converte o 0 para false, e aí não renderiza o 0 na tela.
  • 30. Boas Práticas de React e TS 2 - Use uma lib externa para Data Fetching É sempre bom utilizar as Apis nativas do JavaScript como fetch, porém existem libs que podem ser usadas no React como React Query ou SWR que utilizam Hooks para fazer essa comunicação com o servidor. Eles já vem com features prontas de Tratamento de Erros, Cacheamento, Hidratação de componentes, Gerenciamento de Estados e etc. que se fossemos fazer do zero, iríamos perder muito tempo reinventando a roda. Caso trabalhe com APIS GraphQL, existem clientes como o Apollo, que já possui o conceito de estado pronto.
  • 31. Boas Práticas de React e TS 3 - Se o seu APP é grande o suficiente: Use uma lib para gerenciar o estado Em diversas situações o Context API nativo do React não vai funcionar como um gerenciador de estado da sua aplicação. Utilizar o Context API em situações como quando só precisamos passar dados de um componente para outro, ou para compartilhar dados em baixo volume, é a solução ideal para o que precisamos Mas em outras situações o Context API é apenas um injetor de dependências e não serve para tratar gerenciamento de estados complexos, ou que sejam atualizados com alta frequência. Para isso possuímos os Redux com Redux Toolkit, ou Mobx ou Recoil. Escolher uma lib para gerenciar o estado da nossa aplicação pode ser uma decisão acertada, pois geralmente o estado processa dados importantes da aplicação e se for arquitetado e manipulado de forma errada pode causar grande perda de performance ou até quebrar nossa aplicação.
  • 32. Boas Práticas de React e TS 4 - Não escreva código Hardcoded. Utilize um objeto de config para isso Um exemplo é esse código ao lado com um arquivo de configuração de rotas. Ele vai ser interpretado por um AppRoutes que vai mapear cada objeto desse array e vai renderizar uma rota da nossa aplicação
  • 33. Boas Práticas de React e TS 4 - Não escreva código Hardcoded. Utilize um objeto de config para isso Ao lado temos o componente AppRoutes que possui apenas a lógica de renderização das Rotas, não tendo as rotas em si. Separando a responsabilidade de cada componente, um para os dados, e um para a interpretação dos dados.
  • 34. Boas Práticas de React e TS 5 - Faça a tipagem correta dos seus objetos/props e funções Tipar nossos objetos com o tipo errado, ou com any, pode ocasionar problemas na hora de renderizar nossa aplicação. Especialmente em casos em que não fazemos nullcheck nos nossos dados. um exemplo comum de componente com tipagem incorreta:
  • 35. Boas Práticas de React e TS 5 - Faça a tipagem correta dos seus objetos/props Qual o problema com o componente anterior? 1- Estamos usando any como tipo do prop data, aceitando qualquer valor que venha no componente. 2 - caso esse prop data seja nulo ou undefined, ele vai quebrar a renderização do componente. 3 - Não estamos forçando o tipo de retorno do nosso Componente. na teoria ele pode retornar qualquer coisa. 4 - Para isso corrigimos nosso componente dessa forma:
  • 36. Boas Práticas de React e TS 5 - Faça a tipagem correta dos seus objetos/props No exemplo do slide anterior, estamos especificando uma interface para a props data, que recebemos no nosso componente, e que ele é um objeto de um array (por isso fazemos map dele), e antes de fazermos esse map, realizamos o nullcheck, pra saber se essa prop data existe e não é nem null e nem undefined. Caso seja retorna null e não quebra a nossa aplicação.
  • 37. Boas Práticas de React e TS 6 - Centralize componentes externos Caso você utilize componentes de outras libs e packages,é uma boa prática, você centralizar em uma pasta shared todos os imports dos seus componentes, pois quando você importar nos seus componentes locais, os mesmos não precisam saber da onde vem esses componentes externos. Facilitando inclusive a troca de libs caso seja necessário. Assim você tem apenas uma fonte de informação que é facilmente substituível, ao invés de ter que substituir em sua aplicação inteira.
  • 38. Boas Práticas de React e TS 7 - Utilize Hooks Hooks veio para ajudar no re-uso de lógica e compartilhamento de estado entre componentes da nossa aplicação. Antes dos Hooks, a forma de fazer isso era através de High Order Components ou Render Props. O ruim de usar HOC, é que os valores que precisamos vem dentro de props, que não temos uma idéia clara se vem do componente pai, ou do componente que estamos adicionando no HOC. com Hooks conseguimos separar a parte lógica do componente, e reutilizá la onde quisermos em nossa aplicação. Além de deixar nosso componente muito mais legível.
  • 39. Boas Práticas de React e TS 8 - Preste Atenção nos Re-Renders: useMemo() x useCallback() Quando atualizamos as props de nosso componente ele causa re-render em todos sua estrutura, seja o filho ou o próprio componente pai, inclusive em partes/estruturas do componente que não foram atualizadas. Para evitar isso existem dois Hooks que nos ajudam a não causar Re-renders desnecessários: useMemo() x useCallback() useMemo(), serve para guardamos valores em cache, e só atualizar quando o valor da dependência que especificamos no hook mudar. useCallBack(), serve para guardar um método em cache ,que só vai ser chamado/atualizado se as suas dependências forem atualizadas. A importância de utilizarmos esses Hooks, é especialmente porque ele evita muitos problemas de performance para o usuário.
  • 40. Boas Práticas de React e TS 9 - Utilize Object Literals ao invés de switch Muitas vezes quando precisamos fazer algum código condicional como muitos if/else,utilizamos switch/case, mas o problema do switch case é que ele não escala muito bem. Object literal é mais simples. podemos por exemplo usar para instanciar um componente:
  • 41. Boas Práticas de React e TS 9 - Utilize Object Literals ao invés de switch Nesse exemplo, temos no slider anterior um Componente de Página que centraliza todos os componentes de página, e que abstrai para outro componente a lógica e UI da página,e abaixo seria o componente principal que apenas instancia esse componente centralizador com o "type" do componente de que queremos.
  • 42. Boas Práticas de React e TS 9 - Utilize Object Literals ao invés de switch Qual a vantagem de usar essa abordagem para Componentes, lógica de código, casos de exceção etc? Seu código fica mais organizado. Mais intuitivo. Caso você queira trocar um componente, remover, ou até testar seu código ele fica muito mais simples para atingir esses resultados. E escalavel. Porque nesse exemplo anterior, sabemos onde está sendo instanciado todos nossos componentes de páginas, e assim podemos a partir do Object Literal instanciar mais componentes, que separando a parte lógica de um componente de Rota ( como o do slider anterior ), podemos não só organizar melhor nosso código, mas re-utiliza-lo também.
  • 43. Boas Práticas de React e TS 10 - Abstraia Serviços Uma boa prática para tornar sua aplicação escalável, é ter uma função que retorna os mesmos tipos de componentes, ou serviços por exemplo. Vamos dar um exemplo de abstração de um serviço: Primeiro criamos um serviço genérico de Fetch que vai ser utilizado em todos os nossos serviços:
  • 44. 10 - Abstraia Serviços No nosso serviço específico de busca de artigos, apenas passamos o parâmetro da URL que queremos para nosso serviço de fetch genérico. Boas Práticas de React e TS
  • 45. 10 - Abstraia Serviços agora podemos fazer um import mais limpo e usar nosso serviço dessa maneira: Boas Práticas de React e TS
  • 46. 10 - Abstraia Serviços Encapsulando nosso serviços em um só lugar, fica mais fácil de substituir eles depois: Boas Práticas de React e TS
  • 47. O que é SOLID?
  • 48. SOLID é um acronimo para 5 principios de software que tem como objetivo definir práticas que mantém o software mais intuitivo, flexível e manutenível.
  • 49. Conceitos de SOLID para React SOLID , um conceito muito difundido na programação orientada a objetos pode ser usada em programação funcional? vamos ver o que o Uncle Bob tem a dizer sobre isso: Tweet traduzido de: https://twitter.com/unclebobmartin/status/1164511654618550273
  • 50. Quais são os conceitos Solid? S de Single Responsibility Principle: Um Componente ou função só deve fazer uma coisa e fazê-la direito.
  • 51. Um componente comum em projetos React: Aqui um componente de listagem de gatos: ( continua no próximo slide)
  • 52.
  • 53. Single Responsibility Principle no React/TS Qual o problema com esse componente? Vamos lá: 1 - Ele define um estado inicial 2 - Depois ele define uma função redutora para gerenciar esse estado 3 - Ele define uma interface que vai ser o tipo principal do objeto que é a razão desse componente 4 - Ele define um Componente, que faz 1 - Um serviço de chamada de API e uma filtragem desse resultado de API 5- Ele instância esse objeto resultado da chamada da API, e então retorna os dados dentro de um componente HTML.
  • 54. Single Responsibility Principle no React/TS Como resolver os problemas definidos no slide anterior respeitando o princípio de Single Responsibility? 1 - Podemos abstrair o código do useReducer() para uma função redutora separada para tratar o state da nossa função. 2 - Podemos abstrair o código dos hooks useEffect: 1 - passando o fetch para um serviço genérico HTTP. 2 - Criando um hook específico para lidar com a resposta desse serviço e fazer o filtro que esperamos do objeto. ex: useCatHook() 3 - o hook useCatHook(), voltaria 2 propriedades , a resposta = cats, e o isLoading para trazer se a resposta já foi obtida ou não. 4 - Fariamos um componente UI, que faria um map no objeto cats e imprimiria nossa lista com dados dos gatos. 3 - No final iriamos só renderizar o componente final que organiza toda a lógica que precisamos para renderizar a lista de gatos :)
  • 55. Open Closed Principle no React/TS “Robert C. Martin (Uncle Bob) considerou este princípio como o‘ princípio mais importante do design orientado a objetos ’. Mas ele não foi o primeiro a defini-lo. Bertrand Meyer escreveu sobre isso em 1988 em seu livro Object-Oriented Software Construction. Ele explicou o princípio Open/Closed como: ‘Entidades de software (classes, módulos, funções, etc.) devem ser abertas para extensão, mas fechadas para modificação.’ ”
  • 56. Open Closed Principle no React/TS Usando Open / Closed Principle: Assim como já demonstramos com a Abstração de Serviços e Object Literals, no componente abaixo mostramos mais um exemplo de Open Closed Principle, onde não importa quantos tipos de gato podemos criar, não alteramos o código do componente de gatos principal.
  • 57. Open Closed Principle no React/TS
  • 58. Liskov Substitution Principle no React/TS O princípio de Liskov Substitution nos diz que: “Os componentes devem obedecer a algum tipo de contrato.” Basicamente, isso significa que deve haver algum tipo de contrato entre os componentes. Portanto, sempre que um componente usa outro componente, ele não deve interromper sua funcionalidade (ou criar algum efeito colateral indesejado).
  • 59. Liskov Substitution Principle no React/TS Imagine que temos um componente que recebe um dado via props e passa para seu componente filho: E aí renderizamos esse componente no nosso App, passando um objeto key: "value"
  • 60. Liskov Substitution Principle no React/TS Eis que estoura um erro no console Então TypeScript vem para nos salvar! Quando tipamos o prop data do nosso componente estamos atribuindo a ele um tipo único que caso não seja obedecido, vai estourar um erro no nosso Vs Code:
  • 61. Liskov Substitution Principle no React/TS Agora quando tentamos renderizar nosso componente em outro, ele vai acusar erro, caso não respeitamos o contrato entre componentes:
  • 62. Liskov Substitution Principle no React/TS Se substituirmos a propriedade do objeto pela propriedade correta, ele para de acusar o Erro e conseguimos respeitar o princípio de Liskov Substitution
  • 63. Interface Segregation Principle no React/TS O princípio de Interface Segragation nos diz que: “Os componentes não devem depender de coisas de que não precisam.”
  • 64. Interface Segregation Principle no React/TS Imagine que temos nosso componente de gatos pai, que renderiza um Componente com detalhes do gato, e um com imagens do gato, e em ambos passamos nosso objeto cat:
  • 65. Interface Segregation Principle no React/TS Qual o problema com o código do slide anterior? 1 - Ele está passando props desnecessárias para nossos componentes filhos, esse tipo de situação é muito comum quando retornamos a resposta de uma API sem tratar os dados devidos, ou não tipos e passamos os parâmetros certos para nossos componentes 2- Basta passar o objeto correto para nossos componentes filhos e então não violamos mais o princípio de Interface Segregation.
  • 66. Dependency Inversion Principle no React/TS O princípio de Dependency Inversion nos diz que: “Nenhum componente ou função deve se preocupar com a forma como uma determinada coisa é feita.”
  • 67. Dependency Inversion Principle no React/TS Imaginamos que temos um componente que precise fazer o fetch de dados de uma base de cachorros como no código abaixo:
  • 68. Dependency Inversion Principle no React/TS Qual o problema desse código? 1 - Ele Depende de alguns dados remotos que são buscados diretamente no componente. 2- A principal responsabilidade do nosso componente Dogs é processar e renderizar os dados. 3 - Ele não deve se preocupar com a forma como os dados são buscados ou de onde os dados vêm. Este componente sabe demais - e isso é um problema. Imagine que: 1 - Você precise fazer fetch de dados em mais de 50 componentes. 2 - Seu chefe resolve trocar fetch, por axios por exemplo, e você tenha que trocar nos 50 componentes. 3 - Depois ele pede que você faça o cacheamento dos dados.
  • 69. Dependency Inversion Principle no React/TS Como arrumar meu código para não ferir o princípio de Dependency Inversion? 1 - Podemos abstrair toda lógica de fetch de dados para um hook customizável: useFetch() hook por exemplo. 2- Nesse hook podemos usar o axios ou lib que quisermos além de implementar o cacheamento dos dados. 3 - Assim não precisamos implementar o mesmo código em mais de 50 componentes, evitando a possibilidade de criar Bugs desnecessários, economizando tempo e manutenção. Como sei se estou quebrando o princípio de Dependency Inversion? 1 - Na maioria dos casos se você está quebrando o princípio de Single Responsibility, você também está quebrando o princípio de Dependency Inversion. 2 - Olhe nos imports do seu componente. Se você não está importando apenas componentes que são responsáveis por renderização no UI (um Modal por Exemplo), você pode estar violando o princípio de Dependency Inversion.