Redux: O passo a passo

redux 11 de Out de 2017

O Redux é uma biblioteca para gerenciamento de estado que segue os princípios da arquitetura flux. Não vou entrar em detalhes profundos, mas o que você precisa entender aqui são alguns princípios básicos dessa biblioteca:

Estado global

Diferente da arquitetura padrão do React, o estado dos componentes não é armazenado na própria classe do componente (exceto casos específicos). Toda e qualquer informação da View carregada por API, banco de dados ou qualquer outro tipo de endpoint é armazenada em um único objeto global chamado State.

Dessa forma, cada componente é manualmente amarrado à uma ou mais variáveis do estado e, dessa forma, sempre que essas informações sofrerem alteração, o componente é atualizado recebendo as novas propriedades.

Seguindo esse conceito, pense em uma aplicação com autenticação e criação de lista de todos, nosso State seria parecido com esse:

{
  auth: {
    username: 'admin',
    name: 'RocketSeat'
  },
  todos: [
    'Fazer café',
    'Ler posts da RocketSeat',
    'Assistir os vídeos do YouTube'
  ],
}

Veja que tenho informações de duas funcionalidades completamente distintas armazenada em um mesmo objeto (e isso é lindo).

Actions

As Actions são objetos que indicam diretamente uma ação realizada no software, essa Action pode ser algo disparado pelo próprio usuário ou algo disparado pela própria aplicação.

A Action possui sempre uma propriedade type única que é utilizada pelo Redux para distinguir qual ação está sendo realizada, esse conceito recebe o nome de Action Type.

// Exemplo de action

{
  type: 'LOGIN',
  payload: {
    username: 'admin',
    password: '123456'
  },
}

Uma boa prática é mantermos toda informação (exceto o type) dentro de uma propriedade chamada payload.

Ainda pensando na ação de login, poderíamos ter três Actions LOGIN_REQUEST, LOGIN_SUCCESS e LOGIN_ERROR. A primeira seria disparada diretamente pelo usuário enquanto as outras duas disparadas pela própria aplicação baseada na resposta da API de autenticação.

Para dispararmos uma Action em nossa aplicação precisamos englobar esse objeto dentro do retorno de uma função chamada Action Creator, essa função então poderá ser acessada por qualquer componente da aplicação:

function loginRequest(username, password) {
  return {
    type: 'LOGIN_REQUEST',
    payload: {
      username,
      password
    },
  };
}

Reducers

Apesar das Actions ouvirem ações realizadas pelo usuário ou pela aplicação, a mesma não realiza nenhuma alteração em nosso estado global. Para alterar qualquer informação no State precisamos utilizar os Reducers.

Todo Reducer ouve todas Actions disparadas pela aplicação e cabe a você decidir quando o mesmo deve realizar qualquer alteração no estado. Seguindo o exemplo da autenticação, teríamos um Reducer para controlar a informação de autenticação do usuário:

function authenticated(state = false, action) {
  switch(action.type) {
    case 'LOGIN_SUCCESS':
      return true;
    case 'LOGOUT'
      return false;
    default:
      return state;
  }
}

O primeiro parâmetro recebido pelo Reducer é sempre o estado atual e podemos inicializar o estado com um valor padrão (nesse caso false). O segundo parâmetro é nossa Action que contém as informações de type e payload.

Realizamos um switch para filtrar as Actions que pretendemos ouvir com esse Reducer e, caso não atenda nenhum caso, apenas retornamos o estado intocado.

Cada reducer controla uma única propriedade no State, mas como essa propriedade pode ser um objeto ou vetor, podemos guardar todas informações referentes a cada “módulo” da aplicação dentro dessa propriedade, por exemplo no caso de autenticação poderíamos guardar mais informações:

// Estado (apenas representação)

{
  auth: {
    authenticated: true,
    user: {
      username: 'admin',
      name: 'RocketSeat'
    }
    token: 'algumtokenlegal',
  },

  // ... outras propriedades do estado
}

Dessa forma, o mesmo Reducer pode alterar mais de uma informação do estado pois elas estão encapsuladas em um objeto que representa todo módulo de autenticação.

Redux + ReactJS (ou React Native)

O grande case da utilização do Redux é unir essas funcionalidades com o poder das bibliotecas ReactJS ou React Native. Por isso, eu fiz uma live no YouTube sobre gerenciamento de estado com Redux que explico todos conceitos acima e crio um projeto com ReactJS + Redux:

Para onde vou?

Com tudo isso que você leu, diria que a melhor forma de realmente entender o Redux é botando a mão na massa (ah vá). Por isso indico você começar com projetos pequenos e ir incrementando com conceitos mais complexos para dominar essa ferramenta.

Se eu pudesse te dar uma dica que eu adoraria ter quando comecei com o Redux é: acesse a comunidade da RocketSeat, isso porque lá temos centenas de programadores empreendedores trocando ideias diariamente sobre Javascript, React, Redux, Startup, etc etc etc…

Ah, não esquece de deixar um comentário caso tenha qualquer dúvida sobre esse processo do Redux (ou se gostou/não gostou do post).

Marcadores

Diego Fernandes

Programador full-stack, apaixonado pelas melhores tecnologias de desenvolvimento back-end, front-end e mobile, é co-fundador e CTO na Rocketseat.