React Redux e TypeScript

React Redux e TypeScript

Nos últimos anos, o desenvolvimento front-end tem passado por uma verdadeira revolução, impulsionada por tecnologias inovadoras e abordagens eficientes, sendo duas delas o Redux e o TypeScript. Enquanto o Redux é uma biblioteca que permite a criação de interfaces interativas e escaláveis, o TypeScript é uma linguagem de programação que adiciona recursos de tipagem estática ao JavaScript, permitindo a detecção de erros durante a fase de desenvolvimento e melhorando a qualidade e robustez do código.

A combinação do Redux e do TypeScript tem se mostrado extremamente valiosa para o front-end, oferecendo uma experiência de programação mais agradável, reduzindo erros e aumentando a eficiência. Dada a importância de ambos, hoje aprenderemos a implementar o Redux no Typescript, desenvolvendo uma aplicação que terá tudo o que é necessário para tal.

O que é o React?

O React é uma biblioteca Javascript de código aberto utilizada por diversas empresas notórias como o facebook, a netflix, o Instagram, etc. Focado em criar interfaces para o usuário de maneira muito mais prática do que utilizando o Javascript puro, o React foi ganhando mais e mais espaço por ser de fácil assimilação, compreensão e adaptação.

O que é um estado?

É muito importante, antes de começarmos a colocar a mão na massa, entendermos o conceito de estado e para que ele serve. Imagine que você tenha uma aplicação que, ao ser realizado determinado tipo de interação (como por exemplo: adicionar um item ao carrinho ou um filtro que limita o que você quer ver),  seja necessário que uma determinada quantidade de informações fiquem temporariamente salvas, com o objetivo de outros componentes ou rotas terem acesso a elas, enquanto a tela não for fechada ou atualizada. Esse lugarzinho onde estas informações ficarão armazenadas é o que chamamos de estado. Sem ele, tudo no React seria uma bagunça ou no mínimo uma dez vezes mais desgastante de ser implementado.

Primeiros Passos

Para entendermos a mecânica principal de uma implementação do Redux no Typescript, criaremos uma aplicação React com duas Rotas, onde uma delas terá um catálogo de itens (chamaremos de “Home”) e a outra exibirá os que foram escolhidos pelo usuário (chamaremos de “ShoppingCart”. Para isto, precisamos criar um projeto React, instalar o gerenciador de rotas (react-router-dom) e, por fim, o typescript. Para isto, execute a sequência de códigos a seguir em um terminal aberto no diretório que você deseja que fique armazenado seu projeto:

npx create-react-app shopping-cart
cd shopping-cart
npm i react-router-dom
npm install react-redux
npm install @reduxjs/toolkit
npm install -D typescript@4.9.5
npx tsc --init

Após a execução, remova os arquivos desnecessários gerados pelo “create-react-app” e altere os arquivos “App.js” e “index.js” para o formato “.tsx”. Com todas as implementações devidas para criar as rotas que utilizaremos, seu código deve estar parecido com o exibido a seguir:

Figura 1 - Implementação do arquivo index.tsx com o componente “BrowserRouter” e tipagem de constante “root”
Figura 2 - Implementação de “app.tsx” com criação das rotas “home” e “shopping-cart”
Figura 3 - Componente Home
Figura 4 - Componente ShoppingCart
Figura 5 - Componente “tsconfig.json”

Estamos com quase tudo preparado para começar a implementar o Redux! Falta popular o componente Home com alguns itens que poderão ser clicados e salvos no estado que criaremos. Utilizaremos um dos endpoints da API do Mercado Livre para isto:

Figura 6 - Função que extrai dados de uma API e salva em um estado

Na figura 6, utilizamos a função “fetchItems” para  acessar um endpoint da API e registrar no estado “list” uma lista de itens. Nas figuras a seguir (Figuras 7 e 8) faremos a implementação que irá acessar estes dados e exibi-los na tela. Você notará que o método de estilização utilizado foi o Tailwind, que utiliza o modelo atomic css, onde cada classe concedida possui uma única função, como por exemplo transformar o estilo de um texto em itálico ou alinhá-lo à direita. Você pode estilizar sua aplicação da forma como achar melhor, visto que nosso objetivo vai além.

Figura 7 - Função que extrai dados de uma API e salva em um estado
Figura 8 - Função que extrai dados de uma API e salva em um estado

Para cada item (percorremos cada um deles por meio do “map” utilizado na linha 52 da Figura 7), teremos uma imagem, um título, o link de acesso ao item no mercado livre (linhas 55, 62 e 63 da figura 7, respectivamente), o preço e um botão (linhas 65 e 68 da figura 8), ainda sem nenhuma funcionalidade atrelada, onde futuramente usaremos para inserir o item no estado global criado via Redux.

Figura 9 - Execução em Browser do componente Home

Configurando o Redux

Agora que na nossa aplicação só falta praticamente a implementação do Redux, chegou a hora de instalar os pacotes necessários para tal. execute o código a seguir em um terminal inicializado na pasta raiz do seu projeto:

npm i react-redux @reduxjs/toolkit

Começaremos criando um diretório redux, onde dentro dele, criaremos mais dois arquivos de extensão “.ts”, chamados “store” e “slice”.

O Redux Toolkit possui uma função chamada “createSlice”, que será utilizada para descrever, principalmente, ações no estado global da aplicação para inserir, atualizar e remover dados. O “createSlice" recebe como parâmetros um objeto com três campos:

  • “name” - recebe como valor uma string que será utilizada como identificador;
  • “initialState” - possui o estado global inicial, ou seja, quando inicializamos a aplicação;
  • “reducers” - deverá conter um objeto com as funções que realizam ações no estado global (por enquanto, como poderá ser visualizado na figura 10, este campo estará vazio, pois estamos apenas implementando o básico da estrutura. Logo mais, quando formos inserir dados no estado global, criaremos juntos estas funções).
Figura 10 - Implementação do Slice

Note que realizamos duas exportações no arquivo “slice.ts”. Uma delas (linha 13 da figura 10), a padrão, utilizaremos no store e, a outra (linha 15 da figura 10), utilizaremos para acessar as informações contidas no Redux.

Chegou a hora de implementar o arquivo “store.ts”. Enquanto no “slice.ts” nós fazemos todas as atividades voltadas para a manipulação do estado global, no “store” nós criaremos o armazenamento. Utilizamos a função “configureStore” para isto, passando como parâmetro um objeto, que possui uma chave chamada “reducer”. Este, por sua vez, terá como um valor um objeto que irá conter todos os “reducers” que possuímos na nossa aplicação (como no nosso caso criamos apenas um chamado slice, exportado na linha 13 da figura 10, iremos criar um único conjunto chave e valor):

Figura 11 - Implementação do Store

Inserindo dados do Redux

Para manipular o estado global gerado com o redux, utilizamos o hook ”useDispatch”. É muito simples de usar, inclusive: você passa como parâmetro uma função (que será uma ação criada no “reducer”) e esta função irá realizar algum tipo de mudança no estado global.

Para exemplificar, iremos atribuir o uso deste hook aos botões de adicionar que criamos para cada item na página “Home”. Primeiro, criaremos uma função no reducer que recebe como parâmetro um objeto e adiciona este objeto a uma lista:

Figura 12 - Criando a função addFavorite

Note que as funções que utilizamos como argumento da chave “reducers” (linha 16 da figura 12) recebem dois parâmetros: um estado, representado por state e equivalente ao estado atual da aplicação, adicionado diretamente pelo próprio redux, além de uma action, que é um objeto que possui as chaves “type” e “payload”. Como é possível notar na linha 17 da figura 12, estamos utilizando apenas o payload desestruturado, pois é nesta chave que são passados os parâmetros que utilizamos na aplicação.

Por fim, iremos importar o “useDispatch” na nossa página home e atribuí-lo ao botão de cada item, passando como parâmetro a função “addFavorites”, que terá por sua vez como parâmetro o conteúdo do item em questão:

Figura 13 - Importando o Hook “useDispatch” (e atribuindo a uma constante) e a função “addFavorite”
Figura 14 - Implementação do “useDispatch” (linha 74)

Por fim, precisamos ceder o store (o armazenamento do estado global), para a nossa aplicação. Na função “index.tsx” utilizaremos o componente Provider, que possuirá uma propriedade chamada “store” que receberá como valor o “store” que criamos:

Figura 15 - Criação do Provider (linha 12)

Agora, já estamos salvando dados no estado global criado com o redux. Mas e como acessar estes dados? Veremos como fazer isso agora!

Acessando dados do Redux

Enquanto o “useDispatch” insere, altera e/ou remove dados do estado global, o hook responsável por acessar estes dados é o “useSelector”. Ele recebe como parâmetro a função “useSlice” que criamos na linha 15 da figura 10. Após atribuir o “useSelector” a uma constante, acaba por ser mais do mesmo: acessamos a chave “list” dentro do estado e mapeamos a lista nela contida, criando um componente para cada elemento:

Figura 16 - Importação e implementação do “useSelector” (linhas 3 e 6)
Figura 17 - Mapeamento da lista contida dentro do estado global do redux
Figura 18 - Aplicação em execução

Considerações finais

No artigo de hoje aprendemos a utilizar o React Redux dentro da linguagem Typescript, destrinchando todas as implementações necessárias para tal. Lembre-se que andar com a documentação debaixo do braço é extremamente importante quando estamos aprendendo novas linguagens, frameworks ou bibliotecas!

Se você achou esse artigo interessante, gostaria de tirar quaisquer dúvidas ou somente está afim de trocar uma ideia sobre esses e mais assuntos, você também pode entrar em contato comigo, seja por meio do e-mail bruno.cabral.silva2018@gmail.com ou pelo meu perfil do Linkedin!

Te espero ansiosamente!

💡
As opiniões e comentários expressos neste artigo são de propriedade exclusiva de seu autor e não representam necessariamente o ponto de vista da Revelo.

A Revelo Content Network acolhe todas as raças, etnias, nacionalidades, credos, gêneros, orientações, pontos de vista e ideologias, desde que promovam diversidade, equidade, inclusão e crescimento na carreira dos profissionais de tecnologia.