Introdução simples ao Redux

Uma explicação direta, leve e divertida sobre Redux!

latrova commited 1 ano, 9 meses ago
×

Você provavelmente já encontrou por aí muitos tutoriais sobre React + Redux, porém nenhum explicando de maneira simples e direta o por quê de se utilizar Redux e quais suas vantagens... Até agora!

Se você assim como eu terminava de acompanhar o acompanhar um desses tutoriais e não sabia bem o que estava fazendo...

Prepare-se pra entender tudo de maneira bem simples agora mesmo!

Antes de começar

É necessário você ter conhecimentos básicos sobre React. Entender o que é um componente, como funciona state e props, e ter noção sobre como funciona uma REST API.

O que você vai ver

  • Explicação sobre o funcionamento do Redux
  • Exemplo de cenário onde o Redux seria útil
  • Elementos básicos que compõe o Redux

O que você não vai ver

  • Como integrar Redux ao seu projeto
  • Como criar um projeto com Redux
  • Projeto de exemplo

Agora podemos começar.

Fatos rápidos

  • Redux não faz parte do React, nem é exclusivo, é possível utilizar Redux com Angular 2
  • Você consegue criar uma aplicação completa sem Redux
  • Redux é um módulo que armazena um estado global para sua aplicação.

Cenário

Vamos imaginar que você possua um sistema que liste algumas vendas efetuadas a alguns clientes. Você possui 2 componentes:

SalesTable e CustomersTable

Ambos os componentes solicitam dados da api.awesome-sales.com nos endpoints customers e sales e respondem da seguinte forma:

/customers

[
   {
       "id": 1,
       "name": "Jhon Doe",
   },
   ...
]

/sales

[
   {
      "id": 32,
      "date": "2017-07-17",
      "total_cost": 52.99,
      "customer_id": 1 
   },
   ....
]

Por fim, você deseja que sua CustomersTable exiba os seguintes dados:

+----+------------+--------------+-------------+
| Id | Vendido em | Vendido para | Vendido por |
+----+------------+--------------+-------------+
| 32 | 17/07/2017 | Jhon Doe     | R$ 52,99    |
+----------------------------------------------+

A treta

Note que a api utilizada não retorna o nome do cliente, apenas seu id. Antes de discutirmos uma solução, gostaria de adicionar uma regra: Você pode consumir a API, mas não pode altera-la. Como resolver?

Fazer requests para customers/:id?

NÃO! imagine que temos 50 vendas e todas com um cliente diferente, isso resultaria em 50 requests desnecessárias para nossa api.

Certo, então o que devemos fazer?

Vou adicionar mais uma informação: Antes do usuário ter contato com a SalesTable, ele acessou a CustomersTable. Se isso realmente aconteceu, podemos garantir que as informações que desejamos estão no state da CustomersTable.

component states

Compreende o problema? Precisamos de uma forma para manter um estado compartilhado, onde vários componentes possam acessar dados e informações comuns. Coisa que nosso Redux faz muito bem ao manter um “estado global” da aplicação que pode ser injetando via props em nossos componentes.

O que pode ser representado da seguinte forma

redux global state

Embora o objetivo deste artigo não seja ensinar Redux, acho justo comentar um pouco sobre a mágica que ocorre de baixo dos panos.

O Redux é composto de 3 elementos (Posso dizer 6 se adicionar Store, Provider e Middleware)

  • Actions
  • Actions Creators
  • Reducers

Actions

É o nome que vai descrever uma ação. Com base no cenário que citamos acima, posso imaginar que teríamos as seguintes actions:

  • FETCH_SALES
  • FETCH_CUSTOMERS
  • SAVE_CUSTOMERS
  • SAVE_SALE
  • [Outros]

Parece simples, certo? Parece por que é simples mesmo. Action representa apenas um nome, nada mais. Ele apenas notifica o Redux de que algo ocorreu, mas não aplica a mudança em si.

Conversa entre uma Action e o Redux

Action: Ei, Redux! Eu vou solicitar os clientes (customers) da API! Redux: Ok :) Action: Ei, Redux! Já estou com os clientes (customers). Pega aqui ó (entrega um array) Redux: Ok :)

Viu? Eu disse que era simples.

Actions Creators

Você provavelmente ainda vai se confundir bastante entre Action e Action Creator, simplesmente por que estão diretamente relacionados e tem nomes bem similares. Sua única função é ajudar a criar a action da forma correta.

const RECEIVE_CUSTOMERS = "RECEIVE_CUSTOMERS"; //Action

const receiveCustomers = (customers) => {
    return {
        type: RECEIVE_CUSTOMERS,
        payload: customers
    }
}

Um action creator pode ficar mais complexo quando envolver uma request pra api, pois uma action pode disparar outras actions. Segue um exemplo adaptado da Documentação do Redux.

  return function (dispatch) {
        dispatch(requestPosts(subreddit)) //Primeira action

    return fetch(`https://www.reddit.com/r/${subreddit}.json`)
      .then(
        response => response.json(),
        error => dispatch(receivePostsFailed(error) //Outra action
      )
      .then(json =>
        dispatch(receivePosts(subreddit, json)) //Outra action
      )
  }
}

Note que sempre são disparados no mínimo 2 actions. A primeira para notificar a aplicação que tem uma requisição em andamento, a próxima para notificar do resultado (independente se bem sucedido ou não).

Reducers

O Reducer é o responsável por determinar o novo estado global da aplicação. É basicamente uma função que recebe o estado antigo, a ação disparada e retorna o novo estado.

reducer(prevState, action) {
    ...
    return newState;
}

Conclusão

Com base no que lemos até aqui, podemos afirmar que: Um component dispara uma action com ajuda de um action creator para o Redux. O Redux, por sua vez, passa a action para o reducer que atualiza o estado global do Redux, que finalmente injeta o novo estado via props para os components.

E é isso! Não deixe de comentar abaixo se gostou do formato do post, ou se faltou alguma informação relevante. Sugestões e melhorias são sempre bem vindas!

E agora?

Se ainda quiser ler mais sobre o assunto, eu indico:

blog comments powered by Disqus