Loading ...

O Blog de Tecnologia da Geofusion

Afinal, o que é o Redux?

Afinal, o que é o Redux?

Eu comecei a olhar para o Redux como uma forma de resolver meus problemas quando minhas aplicações, começaram a ter complexidades maiores na renderização em respostas de alterações de estados dos meus componentes. Então decidi escrever esse artigo para as pessoas que estão analisando o Redux e tentando entender o que ele é e se ele deve ou não ser usado.

A primeira coisa que gostei do Redux foi como o criador, @dan_abramov, fez a abordagem do framework. Além de escrever textos no Medium sobre o Redux, existe uma video aula de graça, no Egghead, aonde ele lentamente explica como funciona o Redux.

O Redux é baseado no Flux. Tanto um quanto outro tem como idéia ter um maior controle nos estados de uma aplicação. Mas eles são diferentes. Começando pelo Flux ser uma arquitetura e o Redux ser um framework.

Achei o Redux fácil de implementar, mas tive problemas para entender depois como comunicá-lo com o React e a realização de mudanças assíncronas. Para coisas pequenas talvez o boilerplate é grande, e não seja necessário usá-lo.

O que é o Redux?   

O Redux apareceu para mim porque eu precisava que as minhas mudanças de estado fossem controladas. Eu tinha por exemplo, muitos casos que uma simples seleção de um dropdown, fazia com que eu tivesse que varrer várias partes do meu código para responder a essa mudança.

Na verdade eram 3 dropdowns, uma de País, uma de Estado e uma de Município. Dependendo da escolha, um determinado número de campos para o usuário preencher iria mudar e o meu mapa iria renderizar. Sem contar que o campo de Estado renderizava quando o campo de País mudava, e por aí vai. Eu tinha várias partes do meu sistema que precisavam renderizar de acordo com a mudança no estado.

O Redux ataca isso sendo um container do meu estado da aplicação,  aonde ele centraliza essas mudanças. Em uma aplicação, uma View pode encadear uma mudança num Model que pode encadear uma mudança em outra View. E aí, corremos o risco de perder o controle nos redraws

Detalhando o Redux

Eu achei a melhor maneira de entender o Redux pensando como um pipeline, que começa lá no momento que alguma coisa acontece no sua aplicação e terminando na aplicação se redesenhando em todas as partes necessárias.

1 –  Ação : Onde tudo começa

Essa primeira parte é uma ação. A ação é a única maneira de mudar os estados de uma aplicação. Quando algo em minha aplicação, como por exemplo, realizar uma busca de um amigo no Facebook pelo nome dele, uma ação será disparada.

E como essa ação é?

Essa ação sempre tem que detalhar qual é tipo dela, no caso, seria um objeto javascript com um TYPE = ‘ SEARCH_FRIEND’. E além disso, os parâmetros, quando necessários. No caso eu passaria uma variável texto BUSCA = ‘ Renan ‘.

2 –  Reducers : Como minha aplicação reage a ação :

Após a ação ser disparada , alguma coisa tem que acontecer. Aonde eu irei mapear a consequência de cada ação da minha aplicação?

Esse é o papel dos Reducers no Redux. São os reducers que em consequência de uma ação, criam um novo estado de acordo com a ação, e devolvem ele para ser o estado da aplicação.  Eles varrem todas as ações definidas, normalmente por um switch-case . Eles centralizam as mudanças de nossos estados.

Um característica importante para o Reducers funcionar corretamente e seguir a idéia de CRIA UM NOVO ESTADO e nunca MUTAR O ESTADO ATUAL.  Isso torna o reducer uma função pura.

E mais uma coisa, os reducers são passados como parâmetros no momento que você inícia uma Store.

3 – A renderização, minha aplicação mudando

Certo, então alguma coisa na minha aplicação aconteceu. Pode ser um click do usuário, por exemplo. E isso disparou uma ação.

consequência dessa ação será feita pelo reducer, que irá criar um novo estado da aplicação, baseado no estado atual e na ação disparada.

O que falta para acabarmos o ciclo?  Bem, falta nossos componentes se redesenharem. Isto é, nossa VIEW precisa entender que  o estado da aplicação mudou, e se redesenhar.

No exemplo abaixo você verá como eu associo o render do componente do React com as mudanças do meu estado da aplicação. Eu farei isso manualmente, mas existem plugins super espertos que conectam o react com o redux que evitam todo esse boilerplate.

4 –  Onde fica meu estado? Quem dispara a ação? Quem associa com um render.  A STORE 

Se você abrir o site do Redux você vai ver três elementos abaixo do Basics, Actions , Reducers e Store. Eu detalhei o pipeline sem falar da Store. A Store é quem faz todas as partes importantes de cada um dos três passos que detalhei anteriormente

Primeiro, a Store é quem armazena meu estado da aplicação. Então somente ela, pode alterar esse estado da aplicação.

Segundo, quando uma Store é criada ela pede como argumento um Reducer. 

Terceiro, a Store é quem consegue alterar o estado da aplicação, por meio de ações. É pela store que iremos disparar ações

Por último, a Store é quem eu associo um listener para as mudanças do estado.

Agora para terminar, irei mostrar um exemplo bem simples implementando o Redux.

Exemplo

Passo 1 – Pensando nas ações

Primeiro eu vou pensar nas ações que irei precisar na aplicação, teremos uma para adicionar no carrinho.  Segundo, preciso de uma ação para fazer o CHECKOUT. Vou definir variáveis recebendo o tipo da função, para ficar fácil de usar

          let ADD_TO_CART = 'ADD_TO_CART';

          let CHECKOUT = 'CHECKOUT';

A minha store precisa dar Dispatch nessas ações,  transformarei essas ações em funções por meio de ACTIONS CREATORS. Que são funções que recebem os parâmetros do estado, e irão retornar um OBJETO JAVASCRIPT, que irá para o Reducer

  function addTodo(value) {
    return {
	  type: ADD_TO_CART,
	  value: value
    }
  }

  function checkout() {
    return {
          type: CHECKOUT,
    }
  }


Passo 2 –  Mapeando as ações com o Reducers


	   const cart = (state = { total : 0}, action = {}) =>; {
   	
           switch(action.type) {
             case ADD_TO_CART:
   	       return  Object.assign({}, state, {
               total: state.total + action.value
  	   });

	   case CHECKOUT:
  	     return Object.assign({}, state, {
    	       total: 0
  	   });

	   default:
   	     return state;
        }
       };

Vou criar minha Store passando o meu reducer


const { createStore } = Redux;
const store = createStore(cart);

E por fim vou criar meu componente de React


 render() {
 
 return (
 <div>
 <div> Carrinho </div>
 <div> Total: {store.getState().total} </div>
 <button onClick={this.checkout}> Checkout </button>
 
 <div>
 <span> Super Nintendo 1000 R$ </span> 
 <button onClick={this.comprar} value='1000' > Comprar </button>
 </div>
 
 <div>
 <span> N64 1500 R$ </span> 
 <button onClick={this.comprar} value='1500'> Comprar </button>
 </div>
 
 <div>
 <span> Game Boy 2000 R$ </span> 
 <button onClick={this.comprar} value='2000'> Comprar </button>
 
 </div>
 </div>
 );
 }
});

E crio  as funções que irão comunicar com minha Store


  comprar(e) {
     	 store.dispatch({
  		 type: 'ADD_TO_CART',
    	value: parseInt(e.target.value),
  	})
  },
 
  checkout(e) {
     	 store.dispatch({
  		 type: 'CHECKOUT',
  	})
  },



const render = () =&amp;amp;amp;amp;amp;amp;amp;gt; {
ReactDOM.render(, document.getElementById("root"));
};

store.subscribe(render);
render();

Resultado final

JSFIDDLE

Bibliografias e Indicações do que ler/ver

Introdução do Redux por Cartoons

Uma maneira legal que foi abordado no Redux

Você precisa do Redux?

Esse texto do criador do Redux conversa sobre a necessidade do Redux

Funções puras

Os Reducers serão funções puras, existem maneiras de se escrever a função sem mutar estados. O video abaixo explica legal como usar isso.

    https://egghead.io/lessons/javascript-redux-pure-and-impure-functions

React Redux

    https://github.com/reactjs/react-redux

Middlewares para Async Functions:

    http://redux.js.org/docs/advanced/Middleware.html

Geofusion.tech

2016 todos os direitos reservados.

www.geofusion.com.br