O que é Redux

O que é o Redux: Entendendo Redux


Esse artigo tem como objetivo esclarecer como as coisas funcionam no Redux. Então, se assim como eu, você precisa de alguns exemplos, analogias e até mesmo uma definição mais exata, vou tentar resolver esse problema agora!

Prontos? Então vamos lá!

Redux

O que é o Redux

Redux é uma biblioteca feita para gerenciar estados em uma aplicação, ela tira a responsabilidade de um componente ter um estado que poderá ser usado por vários outros componentes dentro da sua aplicação e passa isso para um objeto global, que pode ser acessado por qualquer componente, a qualquer momento.

Qual o Problema que o Redux Resolve?

Você já ouviu falar de State Dealing? Imagine que você tem um estado em um Componente A que compartilha esse mesmo estado com seus filhos. Até ai tudo bem, certo? Você passa esse estado por props para os filhos e segue caminhando, cantando e seguindo a canção!

Mas e se você tem um Componente B, que faz parte de outra arvore de componentes que não chega nem perto do Componente A?

Como passar o estado do Componente A para o Componente B? Ai as nuvems já ficaram cinzas, o dia já não parece mais radiante e toca aquela música de triste de fundo, né?

Bom, o Redux veio exatamente para acabar com esses dias tristes! Ele vai literalmente criar um enorme objeto global contento todos os estados que precisam ser acessados por diversos componentes que não tem uma ligação entre si!

Ficou claro? A imagem abaixo pode deixar isso mais evidente!

Explicando a imagem acima: Sem o Redux, você precisa fazer várias pontes para compartilhar um estado no componente do topo da sua arvore até chegar nos componentes mais baixos. Já com o Redux, isso não é necessário, os estados ficam flutuando fora da aplicação, prontos para ser acessados por qualquer componente que queira alterar ou lê-los. Legal, né?

As Ferramentas do Redux

Store – O Rei

O grande astro do Redux é o Store! É nesse lindo, maravilho e potente OBJETO que você vai guardar todos os estados que serão usados globalmente na sua aplicação.

Ou seje, quando um component precisar ler um estado, ele vai consultar o store para ter acesso a ele!

É nele que fica toda a verdade da sua aplicação, ele é o Rei desse reino que chamamos de aplicação!

Mas Viktor, e se eu precisar alterar o estado? Como que eu faço isso?

Calma meu pequeno escudeiro do Redux, temos algumas armas para você usar!

E aqui estão elas:

Actions – O Mensageiro

Actions são ações que serão enviadas do seu component para acionar os Reducers. Ele serve apenas para informar qual função deverá rodar e qual é o dado que ela vai usar como parâmetro!

Em outras palavras, o Action é o mensageiro, é ele que vai avisar para a Mão do Rei (Reducer) quando alguma coisa precisa ser feita ou alterada. Quando você aciona a Action, é como se você estivesse enviando um envolope falando “O componente X quer alterar o estado A usando a função H“.

Como nosso reino é bem burocrático, por mais que as mensagens enviadas do Action sejam para o ***Reducer (Mão do Rei)***, ela primeiro passa para o Valete do Rei, nesse caso, os MiddleWares

MiddleWares – O Valete do Rei

Como vimos acima, nosso reino é bom burocrático e os Mensageiros não tem acesso direto a Mão do Rei. Por isso a existencia dos Valetes. São eles que farão todo o trabalho sujo antes da Mão do Rei ser acionada.

Voltando para o mundo da programação, o MiddleWares vão fazer toda a lógica necessária com o dado que será alterado no estado que, como vimos mais acima, fica dentro do Store.

Relembrando um objeto de classe, temos o setter, que é uma função responsável por alterar os dados dentro desse mesmo objeto.

Objeto de classe… Objeto… Store… ISSO AI! Podemos dizer que os MiddleWares são setters, que vão fazer todo o tratamento do dado, aplicar a regra do negócio, enfim… Qualquer lógica que você queira aplicar no dado antes de coloca-lo no estado será feita aqui!

Reducers – A Mão do Rei

Bom, agora que já temos o mensageiro, que avisa quando um componente quer modificar um estado. O Valete, que faz todo o trabalho e aplica a lógica, qual é a função do Reducer?

Se você está pensando “Apenas atualizar o estado” você acertou em cheio!

Depois que o MiddleWare tratar os dados, ele despacha esse dado para o reducer informar ao Store que o state foi alterado e assim, todos os outros componentes que precisarem usar esse novo estado são notificados!

Seria como se o trabalho feito chegasse na Mão do Rei, e ele passasse somente a informação necessário para o Rei, deixando os detalhes de fora para que o Rei não se preocupe com isso.

Aplicando Redux com ReactJS

  • Disclaimer:

Agora que você entende como as coisas fluem dentro do Redux, podemos colocar a mão na massa e codar! Então prepare seu ambiente de trabalho e vamos lá.

  • Configurando o Redux. Caso você não saiba quais pacotes instalar, só abrir essa lista

Nesse exemplo, vamos construir uma aplicação que mostra uma lista de produtos que podem ser adicionados a um carrinho, ambos terão estados globais que acessaremos através do Store utilizando as ferramentas (e seus complementos) que vimos acima.

Estrutura dos arquivos

Como você pode ver acima, temos uma nova pasta chamada store, dentro dessa pasta ficam nossos States, Reducers, MiddleWares e Actions.

Vamos dar uma olhada mais de perto na nossa primeira pasta, a product.

Pequena e simples, o arquivo contem apenas um array de objetos e a função que vai atualizar o state, no caso, productsReducer.

É aqui, nesse exato momento que iniciamos um estado, por isso o parametro state é iniciado com o foods.

Como essa lista não irá sofrer nenhuma alteração não vamos precisar de actions ou middlewares.

Pasta cart

Olhando de perto podemos encontrar 3 arquivos JS. Actions, Reducer e thunks. Vamos destrinchar o código de cada arquivo.

actions.js

Você se lembra que na explicação dos Actions ele foi descrito como Mensageiro? Repare no que as duas funções retornam…

Exatamente, elas retornam somente um objeto contendo o type e o parametro que foi recebido

product na linha 3 está abreviado, mas pode ser lido como product: product

A mesma coisa acontece no removeFromCart. Simple, não é?

thunk.js

Antes de qualquer coisa, preciso esclarecer que o thunk é apenas um dos MUITOS MiddleWares que existem por ai, parafrasenado um facilitador da Kenzie

Você chuta uma arvore e cai três libs de middlewares” – Araújo, Gabriel

Esse exemplo é focado no Thunk, mas você pode usar outros se desejar.

Então vamos lá!

Na primeira linha do nosso código nós fazemos o import dos nossos Actions que montamos no arquivo actions.js.

A estrutura para usar os middlewares é bem simples, eles são funções que retornam outras funções. A primeira função do thunk recebe o item que vamos modificar no state, na primeira função receberemos um objeto product e na segunda vamos receber apenas um id.

Repare que a segunda parte das duas funções são iguais, recebem os mesmo paremetros dispatch e getState.

  • getState: É uma função que será responsável por acessa um estado global da store. Na linha 13, usamos a descontrução do ES6 para pegar somente o estado do cart dentro da store.
  • dispatch: outra função, ela é o nosso despachante, em outras palavras, o cavalo do nosso mensageiro, que vai mandar o novo estado já tratado para o reducer pelas actions

Explicando a função addToCartThunk: cria uma constante que busca uma chave no localStorage e se ela não existir retornar um array vazio, depois adiciona o product recebido pelo paremetro da primeira função na constante list, atualiza o localStorage com o novo array e manda um aviso para o Reducer atualizar o estado global pelas Actions.

Explicando a função removeFromCartThunk: pega o estado global cart da store com a função getState, filtra esse array pelo ID e retorna todos os IDs que são diferentes do que foi recebido pelo parametro da primeira função e salve esse novo array em uma nova lista. Salve essa lista atualizada no localStorage e manda um aviso para o Reducer atualizar o estado global pelas Actions.

Como vimos na teoria, o middleware faz todo o trabalho pesado da sua aplicação, é ele que vai colocar a lógica que você precisa nos dados antes de salva-los na Store.

reducers.js

Agora que já vimos como fazemos a Action e os middlewares, no nosso exemplo usando o thunk, chegou a hora de vermos como montar o reducer.

É aqui que vamos usar nosso objeto que montamos na action. Como você viu no reducer da pasta products, é aqui que iniciamos o state, nesse caso um array vazio, e o atualizamos com a action.

Com um simples Switch no type que criamos do nosso action, saberemos o que fazer com o item que receberemos. Nesse caso, o type @cart/ADD informa ao reducer que vamos adicionar um produto a lista.

Já o type @cart/REMOVE atualiza a lista que recebemos da action já tratada pelo nosso middleware.

Obs.: Repare no default do nosso switch, ele pode ser usado para fazer uma leitura do estado quando você não quiser altera-lo. Então, quando o reducer não identificar um type valido, ele simplesmente vai retornar o stado atualizado para o componente

Agora que você já viu como montar Actions, MiddleWares e Reducers, falta fazer a ligação de tudo isso, certo? Lhes apresento, a Store!

Vamos começar com os imports

  • createStore: Função responsável por criar a store em si, é essa função que deixa todos os estados globais.
  • combineReducers: Cria um objeto com todos os estados e faz a ligação com os reducers para que a store possa guarda-los
  • applyMiddleware: Permite que os middlewares interceptem as actions antes de chegar ao reducer para fazer toda a lógica.

Essa são as ferramentas complementares para criar a nossa Store. Fica simples entender o que o código está fazendo ao chamar as funções que importamos.

Ainda falta um pequeno detalhe para que tudo possa funcionar, vamos para o arquivo index.js principal da nossa aplicação react.

index.js da pasta src.

Nas linhas 6 você vai perceber que estamos importando um Provider da biblioteca react-redux. esse Provider vai fazer o meio de campo entre o Redux e o ReactJS, permitindo que os componentes tenham acesso a nossa store que configuramos anteriormente.

O Provider precisar ser o ponto mais alto da sua aplicação, pois como ele da o acesso a store, todos os componentes precisam estar abaixo dele para poderem acessar e receber os states.

Pronto, você já vai conseguir usar o Redux na sua aplicação! Mas para que isso flua naturalmente, preciso te apresentar mais algumas coisas, os nossos queridos hooks, para você poder manipular esses estados no seu componente

useDispatch

Aqui nós temos um componente bem simples, quero que você se atente ao useDispatch que estamos importando na primeira linha do componente.

Você já viu esse nome antes, se lembra? É isso ai mesmo, ele é usado nos componentes para acionar os middlewares e fazer nossa lógica! a partir da linha 11 você os vê em ação.

useSelector

Na primeira linha do nosso segundo componente temos o useSelector, essa função vai acessar o nosso objeto com todos os estados da nossa store.

Na linha 4, acessamos somente a chave cart, que contem o nosso array com os objetos do carrinho.

Conclusão

Ufaaa! Agora que a gente não sofrerá mais com State Dealing, podemos usar e abusar do Redux para nossa aplicação! Mas antes de você ir embora, gostaria de deixar um aviso:

Use o Redux somente para os estados que precisam ser acessados globalmente, estados que um número N de componentes precisam acessa-los em vários lugares diferentes. Usar um estado local ainda é recomendado para coisas pontuais, use o bom senso para diferenciar o que precisa ser global e o que não precisa!

+4

Escreva o primeiro comentário

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *