Alura > Cursos de Front-end > Cursos de React > Conteúdos de React > Primeiras aulas do curso React: gerenciando estado com Recoil

React: gerenciando estado com Recoil

Evoluindo o legado - Apresentação

Olá e muito boas-vindas para você que resolveu conhecer esse treinamento sobre gerenciamento de estado com React e Recoil. Eu vou te dar um monte de spoiler do bem para você ver o tanto de coisa legal que temos para trabalhar durante esse treinamento.

Vamos desenvolver em cima de uma aplicação chamada Alura Event Tracker, que é justamente um calendário responsável por adicionar e remover eventos à ele, então ele vai exibir os eventos no calendário. Você pode interagir com essa aplicação e dizer que um evento foi completado, você pode deletar um evento do calendário, você pode mover um evento no draggling drop e mudar o horário e o dia dele, quando ele vai acontecer.

Então tem um monte de funcionalidades legais, porém, vamos começar com um problema grande para resolver. O gerenciamento de estado dele está direto no “app.tsx”. Podemos olhar o nosso código original, vou abrir para dar uma olhada.

Repara, temos uma lista de evento usando um estado local, temos um filtro, temos um método que adiciona evento, que é o deletaEvento, que deleta o evento, que aplica filtro, tem uma lógica que de fato faz o filtro. Está passando um monte de propriedade.

Olha esse elemento ListaDeEventos, que ele está recebendo um monte de prop, se olharmos esse evento, ele pega esse monte de prop e passar para o filho dele.

Então tem um monte de problemas pequenos que podemos ter, esse em específico é o prop drilling, e temos que resolver, vamos trabalhar em cima disso e ver qual é a alternativa que temos hoje, para ao invés de fazer esse gerenciamento de estado em um arquivo grande, e ficar tudo bagunçado, o que podemos fazer e como o Recoil pode nos ajudar a atingir um bom resultado.

Então, no final, vamos ter uma aplicação redonda, com alta coesão, baixo acoplamento, pronta para crescer de forma escalável. Então vem comigo, vamos começar a desembolar esse novelo, porque tem muita coisa legal para fazermos.

Evoluindo o legado - Entendendo o projeto

Olá, que incrível que você está comigo nesse curso sobre gerenciamento de estado com Recoil em aplicações React. Vamos dar uma olhada no projeto que vamos trabalhar e vamos entender essa missão que temos para hoje.

Eu já fiz o download desse projeto, vai ter um link no “Preparando o ambiente” para você baixar, o meu já está pronto. Então, abri a pasta do projeto, vou abrir essa pastado projeto direto no Code. Vou abrir o terminal, vou pedir para ele instalar para mim as dependências, instalar npm.

Ele já instalou, e olha o que precisamos fazer. Vamos dar uma olhada na aplicação primeiro. Vamos colocar npm start, ele vai subir essa aplicação, vamos dar uma olhada na interface e depois vamos entender o problema que precisamos resolver.

Então, parece que ela já está rodando, vou abrir o meu Firefox, “localhost:3000”. Eu tenho o hábito de trabalhar com o Developer Tools aberto. Sempre para poupar um erro, alguma coisa no console, eu já vou saber logo de cara. Então, vou deixar o Developer Tootle aberto no canto, e vamos ver o que essa aplicação faz.

Vamos dar uma navegada, achei alguns eventos, parece que esses eventos estão relacionados com esse outro, então eu posso marcar eles de alguma forma preencher de alguma forma. Estou completando, e está dizendo que já foi executado, vou criar um novo evento e vou colocar “Imersão da Alura”, vou colocar no dia 13/01/2022, vou colocar que ele termina no dia 13/01/2022, e vou colocar o horário das 09:00 da manhã até o meio dia 12:00 e vou salvar.

Limpou o formulário, já adicionou. Ele também tem um filtro, vamos filtrar? Vou filtrar pelo dia 13 de janeiro, que foi o que eu criei. Então, parece que nossa aplicação está funcionando corretamente, tem essa lista de eventos, e vamos ver agora o código por trás disso.

Vou abrir novamente o VSCode, vou fechar esse terminal e vamos começar a olhar os componentes. No “app.tsx”, que é onde a aplicação inicia, eu tenho uma ListaDeEventos, vou minimizar, tem um useState para essa lista de eventos, tem um para o filtro, provavelmente deve ser o filtro para encontrar os eventos.

Tem os call-backs, então eu altero o status do evento, deleto o evento, aplico o filtro. Tem uma lógica que valida o filtro, se eu não tenho o filtro, eu pego a lista inteira, e se eu tenho, eu aplico a lógica de filtro. Da linha 52 a 57 é um if ternário, então minha condição, depois dessa interrogação é se for verdadeiro, e se for falso, é o que está depois dos dois pontos.

Então, se eu não tenho o filtro, eu retorno a lista de eventos, se eu tenho filtro, eu aplico esse método e ele sai passando esses call-backs via prop. Eu tenho uma lista de eventos, vou pedir para formatar.

Então, temos essa lista de eventos que está recebendo várias props de filtro, de alterar status, de deletar eventos, os próprios eventos em si, e os outros estão um pouco mais simples, tem um que passa o método que adiciona evento e os eventos em si. Vamos dar uma olhada neles?

Vou começar pelo calendário, ele está usando Kalend, ele é provavelmente uma biblioteca, vamos ver na parte de cima. É uma biblioteca que monta aquele calendário para nós, tem uma interface que representa o evento do calendário. E ele recebe esses eventos e mapeia. Para cada evento ele pega uma chave. Vamos ver.

Ele está pegando uma data de início, pegou uma string e pegando os 10 primeiros caracteres. Isso, provavelmente ele quer pegar ‘2022-01-15’, a chave vai ser algo parecido com isso.

Então se ele não tem a chave, ele inicia, coloca um array vazio, repara que eu tenho um app, uma chave que é uma string é um array desses eventos.

Então ele validou, se ele não tem a chave, ele adiciona um array vazio, e depois ele pega a chave e faz um push do evento novo mapeando do atual para o novo.

Tem um card, que é só um componente visual, recebe children, renderiza children, que é o CSS, tem meu card de evento.

Ele recebe o evento, alterarStatus, deletarEvento, ele passa isso adiante. Eu tenho um check box do evento também, faz uma validação e ele que altera. Então eu tenho o aoAlterarStatus, que eu recebo via prop, mas só passo adiante. Esse componente de evento nem está usando esse método, essa prop, ela recebe e passa adiante.

Tem um filtro, quem submete o formulário, aplica o filtro, recebe o prop. Temos o formulário em si. Tem um status local todos os campos, aqueles campos que vimos no formulário, ele monta a data também. Submete o formulário salvando o evento e é isso, está bem escrito. Por último temos a lista de eventos.

Nas linhas 10 e 11 é que começa a ficar um pouco complicado e é isso que precisamos resolver. Olha só o que está acontecendo. A lista de eventos recebeu, vamos pegar esse método de alterar status. O “app.tsx” passou para a lista de eventos do aoAlterarStatus. A lista de eventos passou para evento.

Entrando em evento novamente, que por sua vez ele recebe aoAlterarStatus, e passa adiante também. Então olha o prop drilling que está acontecendo. Tem uma prop em cima que vai descendo até chegar no evento. Isso começa a ser complicado, porque imagina, essa aplicação de evento vai crescer e vai receber várias funcionalidades. Do jeito que está, esse arquivo “app.tsx” vai crescer infinitamente, e vai chegar um ponto que não vamos saber mais de onde está vindo cada coisa, como as coisas estão sendo criadas, quem usa uma prop de verdade, quem não usa, quem está só repassando, está confuso.

Então é isso que precisamos resolver, é esse débito técnico que precisamos pagar. Precisamos pegar o projeto Alura Event Tracker, refatorá-lo e deixá-lo pronto para conseguir escalar, ou seja, para receber novas funcionalidades sem ter dor de cabeça, para as pessoas e desenvolvedores que vão trabalhar nele. E como vamos fazer isso nesse caso?

Vamos utilizar uma biblioteca chamada Recoil. Então já vou logo no terminal e vou pedir npm i recoil.

Eu vou instalar essa biblioteca, e eu e você vamos trabalhar em cima desse projeto para extrair esse monte de estado local do “app.tsx”, e deixar isso tudo mais organizado, com uma forma mais simples de se trabalhar, e podendo crescer sem ter dor de cabeça. Então vamos lá, já temos um Recoil pronto, vamos começar a trabalhar, colocar a mão na massa logo, eu te vejo no próximo vídeo.

Evoluindo o legado - Um mundo feito de átomos

Então vamos lá, vamos entender o que é esse Recoil, o que ele faz, quem ele é, como ele resolve esse problema de gerenciamento de estado.

Hoje, o que temos é o nosso “App.tsx” fazendo tudo na mão com o useState, então conforme isso vai crescer, vai ficar infinito, vai crescer infinitamente quando forem entrando os novos status, vai ser uma dor de cabeça para conseguirmos dar manutenção nisso. Vamos olhar para ele.

Então vou abrir uma aba nova no meu navegador e vou acessar “https://recoiljs.org/”. Ele é biblioteca que vamos utilizar. Repara que logo na largada ele já fala que é uma biblioteca de gerenciamento de estado, eu quero ser simples e eu quero ser o mais parecido com o React possível. Esse é o princípio do Recoil, ser simples, minimalista e trabalhar do mesmo jeito que o React trabalha. Então, vamos coloca a mão na massa e vamos começar a extrair esse estado do “app.tsx” para dentro do Recoil.

Então vou deixar a aplicação rodando, vou abrir o VSCode, e a primeira coisa que eu quero fazer é o seguinte, dentro da minha aplicação, qualquer componente que precise ter acesso ao Recoil, ele tem que ser um componente que descenda do Recoil Root, que é um componente que a Recoil entrega para nós.

Então já vou importa-lo, import { RecoilRoot } From ‘recoil’. E o que eu vou fazer? Eu vou colocá-lo no return, e vou jogar toda a minha aplicação dentro dele. O que isso quer dizer? A partir de agora, qualquer componente pode ter acesso a qualquer coisa que fizermos dentro do Recoil. E vamos começar a migrar esse estado.

Eu vou começar pela lista de eventos. Então, vou fechar tudo que eu não estou usando, vou criar um novo arquivo, e onde eu quero criar esse arquivo, eu vou criar uma pasta chamada “State”, de estado, dentro dessa pasta eu vou criar um arquivo chamado “atom.ts”. Por que atom? No conceito do React, o estado é composto por vários átomos. Então cada pedaço do estado é um átomo. E como fazemos para criar esse átomo?

Vou fazer um export consty listaDeEventosState = atom({, que eu já vou criar e quero exportar essa constante, vou chamar essa constante de listaDeEventosState, ela é um estado da lista de eventos. E o que ela é por debaixo dos panos? Ela é um átomo. E o que eu tenho que passar de opção para dentro desse átomo?

A primeira coisa que eu tenho que fazer é dizer a chave dele. Essa chave tem que ser única, os átomos tem que possuir únicas. Então key: ‘listaDeEventosState’.

E o que mais eu vou passar? Vou falar que o padrão dele é uma lista vazia, então embaixo eu coloco default: []. Então criamos um átomo. Vou salvar, e como usamos esse átomo?

Na largada, eu vou trazer os eventos que estavam no “app.tsx” para “atom.ts”, vou pedir para ele formatar o documento, então eu estou inicializando o átomo do mesmo jeito que eu estava inicializando o useState.

E o que eu quero fazer? Eu não quero mais ter essa lista de eventos. Então vou dar um “Ctrl + K + C”, para comentar, depende do sistema que você está usando, mas eu quero comentar essa lista de eventos e repara que ele vai começar a reclamar de um monte de coisa. Tudo que ele estiver reclamando, eu vou comentar.

E tudo que estivermos passando, que é lista de eventos, preciso organizar, não vou passar mais lista de eventos. Ele vai quebrar, não está compilando, vamos arrumar.

Vamos na nossa lista de eventos, e ele não vai mais receber eventos: IEvento[] via prop, não vai mais receber eventos via prop. Inclusive, acabei de lembrar, o nosso átomo, podemos dizer que ele é um átomo de quê? Então vou dizer que ele é um átomo de IEvento e é uma lista, export const listaDeEventosState = atom<IEvento[]>.

Agora, precisamos dessa lista de eventos. Então olha só como fazemos para obter essa lista de eventos de um átomo. Então const eventos = useRecoilValue(listaDeEventosState);.

E ele não está dando mais erro de compilação, ele já sabe que é uma lista de eventos, e eu já passei adiante. O outro lugar que precisamos mexer que ele está reclamando, é o calendário. Então vamos no calendário.

Não vamos mais receber essa lista de eventos, e vamos fazer um “Ctrl + C”, “Ctrl + V”, vamos fazer os imports, const eventos = useRecoilValue(listaDeEventosState) e o nosso state da lista de eventos. Vou salvar. Ele está reclamando que eu estou fazendo um import desnecessário. E vamos testar se vai funcionar.

Voltei, ele está dizendo que tem um monte de erro no console, eu vou recarregar a página. Não deu erro no console. Então isso aconteceu enquanto estávamos manipulando o estado. Repara que os meus eventos já estão aqui, do dia 15 e 16 de janeiro, se eu entrar neles, eu consigo visualizar. Então, já começamos a extrair a lista de eventos, o nosso estado para átomos.

Então vamos revisar. Tínhamos um useState, que tínhamos que passar via prop, isso não existe mais, agora temos um átomo que representa essa lista de eventos. E esse átomo que vai ser a nossa fonte de verdade, ele que vai ter essa lista de eventos. E agora, eu não preciso mais ficar passando via prop em momento nenhum. Quando eu quero utilizar essa lista de eventos, eu falo useRecoilValue, e digo qual é o átomo que eu quero usar, e o Recoil vai me entregar essa lista de eventos pronta.

E repara que tem uma mágica por debaixo dos panos, que o Recoil vai dizer para o componente que ele precisa ser renderizado novamente, sempre que esse valor mudar. O próprio Recoil faz isso para nós. Então do mesmo jeito que o useState funciona.

Lembra que eu falei que a ideia dela é ser bem parecido com o jeito React de ser? É aí que encaixa e tudo faz sentido. Do mesmo jeito que falamos que o useState, quando o estado muda, o componente renderiza, usamos o Recoil Value quando esse Value muda, o componente se renderiza novamente.

Então já extraímos, tiramos aquela lista de eventos que estava no “app.tsx”, colocamos dentro de um átomo, importamos esse átomo para os componentes que precisam dele, e não tem mais essa prop passando de um lado para o outro.

Só que ainda temos muita coisa para fazer, temos que adicionar, alterar e remover eventos desses átomos. Então vamos começar a colocar a mão na massa e colocar tudo isso para funcionar através do Recoil. Vamos lá.

Sobre o curso React: gerenciando estado com Recoil

O curso React: gerenciando estado com Recoil possui 114 minutos de vídeos, em um total de 45 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