Alura > Cursos de Front-end > Cursos de React > Conteúdos de React > Primeiras aulas do curso React: implementando estratégias avançadas de gerenciamento de estado

React: implementando estratégias avançadas de gerenciamento de estado

Mapa do estado em aplicações React - Apresentação

Apresentando o instrutor e sua experiência

Olá! Meu nome é Anthony.

Audiodescrição: Anthony é um homem de pele parda, com olhos castanhos e cabelo preto. Ele usa óculos, boné e uma camisa preta.

Atualmente, atuamos como técnicos de front-end no Luisa Labs, que faz parte do Grupo Magalu, e também temos uma vivência acadêmica. Somos pós-graduados em Engenharia Mobile e mestrandos em Engenharia de Software pela Universidade Federal do nosso estado.

Introduzindo o curso de Gerenciamento do Estado Avançado no React

Estamos aqui para dar as boas-vindas ao curso de Gerenciamento do Estado Avançado no React. Nesta formação, vamos explorar todos os tipos de estado disponíveis no React e as diversas formas de gerenciá-los. Vamos aprofundar os conhecimentos adquiridos em cursos e formações anteriores, além de entender estratégias sobre como, onde e por que aplicar cada um desses tipos de estado.

Para o nosso desenvolvimento, é fundamental conseguir definir e atuar com decisões técnicas mais assertivas. Isso é crucial ao trabalharmos com projetos, sejam eles pequenos ou de larga escala, pois já compreendemos que uma pequena decisão pode definir o rumo de toda uma estrutura ou aplicação.

Requisitos e conhecimentos prévios necessários

Para seguirmos de maneira tranquila, é necessário que tenhamos concluído as formações e cursos anteriores, possuindo uma base sólida em React e algumas bibliotecas. Isso inclui estratégias de requisições, fetch, componentização e conhecimento do React Router DOM. Esses conhecimentos são essenciais para que possamos avançar de forma mais estável.

Embora não seja obrigatório, seria interessante que, dentro desta formação, já tivéssemos concluído o curso de bibliotecas e compreendido o React Query e o ZOB, pois essas serão ferramentas abordadas aqui.

Concluindo a introdução e iniciando o curso

Sem mais delongas, vamos para o curso. Nos vemos lá.

Mapa do estado em aplicações React - Entendendo o conceito de estado em React

Introduzindo o conceito de estado em React

Em aplicações React, sejam elas grandes ou pequenas, nos deparamos com um termo comum: o estado. O termo "estado" aparece frequentemente quando trabalhamos com aplicações React. Mas o que é o estado? Como ele se desmembra? O estado é a representação de um dado, seja ele provisório ou persistente, dentro da nossa aplicação.

Uma forma inicial e muito comum de lidar com estados é utilizando um hook chamado useState. À medida que aprendemos mais sobre a tecnologia, utilizamos esse hook cada vez mais. Chega um momento em que nossa aplicação está repleta de useStates por todos os lados. Nesse ponto, precisamos nos perguntar se essa é a melhor abordagem para lidar com o estado em toda a aplicação. Será que não existem outras maneiras de gerenciar o estado de forma mais efetiva? Podemos afirmar que sim, existem outras maneiras, e vamos discutir sobre isso.

Explorando estratégias de gerenciamento de estado

Qual é o problema? Quando utilizamos uma única estratégia para lidar com o estado de uma aplicação, acabamos limitando o poder do ecossistema React, seja de forma nativa, com os hooks que o próprio React oferece, como as APIs, por exemplo, o Context, ou de maneira externa, utilizando bibliotecas desenvolvidas para cenários específicos.

Na aplicação que estamos mostrando em tela, chamada useDev, temos uma loja virtual, um e-commerce, com categorias e produtos. Cada produto ou item representa um dado, que é salvo dentro de um estado. Mas não é apenas na listagem de produtos que temos a representação do estado. Se observarmos bem, também temos um carrinho, onde podemos salvar um estado. Temos a listagem, como já notamos, e outros meios de inserir dados, como um campo para se inscrever em uma newsletter, onde podemos salvar o texto digitado dentro de um estado.

Documentando e discutindo decisões técnicas

Já conseguimos identificar alguns locais onde um estado pode ser aplicado. Vamos entender quais são as melhores formas de aplicar e utilizar as ferramentas para gerenciar esse estado. Adiantamos que utilizar somente o useState, ou apenas a Context API junto com o useState, pode não ser suficiente. Na maioria das vezes, não será suficiente.

Para começar a entender isso, vamos abrir o VS Code dentro do projeto e iniciar um processo de conversa e documentação ao mesmo tempo. Lembrem-se de que, em outro módulo, onde aprendemos a pensar como uma pessoa Tech Lead em aplicações React, criamos o hábito de documentar e discutir nossas decisões técnicas, e vamos reforçar isso cada vez mais.

Criando o documento "Mapa do Estado da Loja UseDev"

Dentro do projeto, criaremos uma pasta chamada "docs" e, dentro dela, um arquivo chamado stateMap.md. Este será nosso documento em markdown. Vamos colocar um título: "Mapa do Estado da Loja UseDev". Este documento servirá para destrinchar e conceituar os tipos de estado que podemos ter dentro de uma aplicação, seja qual for. Neste caso, focaremos no nosso exemplo, mas esse modelo pode ser replicado para qualquer outra aplicação em que estejamos trabalhando ou que venhamos a atuar.

Agora, vamos definir o corpo do estado e criar uma taxonomia desse estado. De maneira geral, dentro das aplicações React, os estados podem ser definidos em quatro tipos: estado local, estado compartilhado, estado remoto e estado da URL. Vamos entender o que cada um deles é e acompanhar o raciocínio.

Definindo o estado local

Estado Local (Component State)

O estado local define os dados que pertencem a um único componente e que não precisam ser compartilhados. Para gerenciar isso, temos ferramentas como useState e useReducer. O ciclo de vida do estado local começa e termina junto com o componente. A partir disso, começamos a pensar em onde aplicar essa estratégia, sempre considerando o gerenciamento e o ciclo de vida. Quem atualiza esse estado? O próprio componente. Quem consome? Apenas o componente ou seus filhos diretos via props. Essa é uma estratégia que já conhecemos e aplicamos durante toda a trajetória no curso.

Explorando o estado compartilhado

Estado Compartilhado (Shared/Global State)

Vamos elevar o nível e entrar no estado compartilhado, que pode ser um Shared State ou um Global State. A definição dele é: dados que múltiplos componentes distantes compartilham. Se compararmos com o useDev, temos o carrinho de compras.

Na nossa aplicação, temos a página de carrinhos e a página inicial, que compartilham um dado comum: a quantidade de itens no carrinho. Precisamos exibir essa informação tanto na página inicial quanto dentro do carrinho. Assim, temos múltiplos componentes, distantes entre si, que necessitam do mesmo dado. Esses componentes estão distantes na árvore de componentes e precisam acessar ou modificar esse dado. Para gerenciar isso, existem algumas estratégias que discutiremos ao longo deste curso.

Entre as estratégias, temos a Context API, que já conhecemos, o Redux, o JTAI e o Zustand, que é uma ferramenta bastante popular atualmente na comunidade. O Zustand é uma solução simples que nos ajuda a resolver esse tipo de problema.

O ciclo de vida de um estado compartilhado persiste enquanto a aplicação está montada. Enquanto a aplicação estiver rodando, o estado pode ser persistido. Essas estratégias podem estar vinculadas a um local storage ou a um session storage, permitindo que o dado seja persistido por um tempo maior. Qualquer componente com acesso ao contexto ou ao store pode atualizar esse dado, e múltiplos componentes em diferentes níveis da árvore podem consumi-lo. No caso do Context API, todos os componentes abaixo dele na hierarquia da árvore podem consumir ou modificar esses dados.

Compreendendo o estado remoto

Estado Remoto (Server State)

Passando para o terceiro tipo de estado, temos o estado remoto, ou server state. Esses dados residem no servidor e são sincronizados com os clientes. De forma simplificada, isso se refere a requisições HTTP. Quando fazemos uma requisição GET e os dados são retornados, eles estão em um estado remoto, gerenciado pelo estado do servidor. Para gerenciar isso, temos várias ferramentas, como a React Query, o SWR, o RTK Query e o Apollo Client. Essas bibliotecas controlam o ciclo de vida via cache, com particularidades de definição de cache, invalidação, validação e outras estratégias. O servidor, por meio de chamadas API, atualiza esse estado, e todos os componentes que fazem fetching consomem esse estado, compartilhando o cache. Essas bibliotecas oferecem funcionalidades como loading, error, refetch, stale data e cache invalidation, de forma assertiva e direta.

Analisando o estado de URL

Estado de URL (URL State)

Por último, temos o estado de URL, ou URL State. Esses dados devem ser compartilháveis via link e refletir a navegação. Por exemplo, ao entrar em uma loja online, a URL pode aumentar à medida que aplicamos filtros ou acessamos a página de um produto. Podemos copiar essa URL e compartilhá-la, permitindo que outra pessoa veja a mesma página. Para gerenciar isso no React puro, usamos o React Router, com params e outras funções da biblioteca. No Next.js, utilizamos o objeto sshparms. O ciclo de vida é sincronizado com a barra de endereço do navegador, sendo atualizado sempre que a barra é modificada. Os componentes que alteram as query strings ou params atualizam o estado, e o próprio navegador pode alterá-lo manualmente. Os componentes dentro dessa URL consomem o estado, que é bookmarkable, compartilhável e sincronizado com os botões de avançar e voltar do navegador.

Mapeando e caracterizando estados no código

Compreendendo isso, vamos caracterizar e entender os estados presentes no código atual. Neste momento, é recomendado pausar o vídeo, mapear todo o código do projeto disponível, e depois retornar para analisarmos os estados disponíveis e suas características. Vamos avaliar como eles estão sendo usados e como deveriam ser usados, de acordo com as características e tipos de estado que definimos. Tire um tempo para revisar o código, e depois voltaremos para caracterizar os estados na aplicação.

Mapa do estado em aplicações React - Verificando o mapa de estado da aplicação

Verificando o mapa completo dos estados

Voltamos para dentro do nosso StateMap, do nosso documento em Markdown, e vamos agora verificar o mapa completo dos estados dentro da nossa loja UseDev. Antes de mais nada, vamos colar aqui. No Preview, vamos recolher a aba dos arquivos para termos uma visão mais detalhada desse mapa completo dos estados que temos dentro da nossa aplicação.

Definimos as seguintes colunas: nome do estado, tipo, ferramenta atual utilizada no projeto, ferramenta ideal, localização do estado, quem atualiza, quem consome e se precisa de link. Criamos essa tabela para seguir como uma ferramenta, como aprendemos no curso de como pensar em aplicações React, é um mapa de decisão. A partir disso, conseguimos ter uma noção maior de como estruturar o projeto e quais alterações podemos fazer. Isso é muito útil para mapear refactor (refatoração), melhorias e novas entregas, o que se espera de uma pessoa desenvolvedora sênior.

Analisando estados específicos

O primeiro estado que temos é o estado de Query, que está na busca do header. Ele é um tipo local, a ferramenta atual que utilizamos é um useState, e a ferramenta ideal para ele também é um useState. Portanto, está tudo tranquilo, ele está dentro do header, quem atualiza é a pessoa usuária via input, quem consome é apenas o reader e ele não precisa de link.

O newsletter.email segue o mesmo padrão. Já o cartItems, por exemplo, é um tipo compartilhado e atualmente está dentro de um context.api, mas também utiliza localStorage. A ferramenta ideal para ele pode ser um context.api, então também está adequado.

O nosso cartCount também é compartilhado e derivado, utilizando o context. Ele é derivado do cartItems, está dentro do cartContext, e sua atualização é feita de forma automática. Quem consome é o header, lembrando da contagem de itens no carrinho. Portanto, temos uma abordagem que faz sentido.

Explorando estados remotos e derivados

Nós chegamos ao estado número 5, que é o categories. Este estado é do tipo remoto, mas atualmente, dentro do código, estamos utilizando o useState junto com axios e, consequentemente, o useEffect. No entanto, conforme discutido anteriormente, para estados providos via API, protocolo HTTP ou back-end, existem ferramentas específicas que podemos utilizar para melhorar esse fluxo, como o React Query.

Atualmente, o estado categories está na homepage. Quem o atualiza é a rota da API, na barra categories, e quem o consome é o componente categories. Não há necessidade de um link, mas, dado esse contexto, precisamos de um refactor, ou seja, uma mudança de ferramenta ideal para essa aplicação.

Temos mais definições disponíveis, e vocês podem explorar cada um desses estados. Por exemplo, temos estados derivados como o slogan product, que, como vimos anteriormente, as ferramentas já estruturam para nós, eliminando a necessidade de montá-los manualmente. Atualmente, estamos utilizando o useState para lidar com isso, mas ele poderia ser gerenciado pelo React Query.

Outro exemplo é o Product ID, que utiliza o useParams, um hook do React Router. A ferramenta ideal para ele também é o useParams. Este estado é definido via URL, sendo modificado pela própria navegação, e quem consome é a Product Details Page.

Disponibilizando um guia de decisão

Disponibilizamos também um guia de decisão, que ajuda a determinar onde o estado deve residir. Criamos um fluxograma que pode ser utilizado para definir, de maneira mais rápida, onde colocar o estado que está sendo construído. Este fluxograma mental auxilia na definição, fazendo algumas perguntas: o estado precisa ser compartilhado via link ou URL, como filtros, coordenação, paginação, ID? Se sim, é um estado de URL. Caso contrário, os dados vêm do servidor? Se sim, é um estado remoto. Se não, existem múltiplos componentes distantes que precisam ler ou modificar esse estado? Se sim, é um estado compartilhado, seja global ou shared state. Caso contrário, será um estado local.

Com este guia, será possível definir, de maneira mais prática e facilitada, onde colocar cada um dos estados da aplicação.

Sobre o curso React: implementando estratégias avançadas de gerenciamento de estado

O curso React: implementando estratégias avançadas de gerenciamento de estado possui 339 minutos de vídeos, em um total de 52 atividades. Gostou? Conheça nossos outros cursos de React em Front-end, ou leia nossos artigos de Front-end.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Aprenda React acessando integralmente esse e outros cursos, comece hoje!

Conheça os Planos para Empresas