React Redux

Para quem não conhece, React e Redux são duas bibliotecas indepentes. Posso usar React sem Redux e vice-versa.

Mas em uma aplicação mais robusta onde temos várias árvores de componentes, é altamente recomendado usar o Redux para gerenciar os estados. 

Pois controlar estados na árvore de compoentes fica muito complicado a longo prazo como mostra a figura:

Imagem 

O componente que iniciou a mudança, dispara a mesma direto para o store que por sua vez vai se encarregar de renderizar os componentes que estão usando o estado alterado. 

Como de costume, vamos nos basear no projeto criado nesse post. Esse é um projeto cordova (poderia ser um projeto node js puro) com webpack e as dependências do react e react-dom. 

Agora vamos instalar as depedências do redux e react-redux

 npm install --save redux react-redux

Ou para quem usa yarn:

 yarn add redux react-redux

Alterando o arquivo src/app/index.js deve ficar assim:

 import React from 'react';
 import ReactDOM from 'react-dom';
 import {combineReducers, createStore} from 'redux';
 import Contador from './Contador';
 import contadorReducer from './contadorReducer';
 import {Provider} from 'react-redux';
   
  const reducers = combineReducers({
     contadorReducerChave:contadorReducer
  });
  
  ReactDOM.render(
         <Provider store={createStore(reducers)}>
              <Contador/>
         </Provider>
         ,document.getElementById("meu-app"));

Toda nossa aplicação fica dentro do compoente Provider. Ele que se encarrega de renderizar os componentes ligados aos estados alterados.

Dentro da mesma pasta src/app vamos criar um arquivo Contador.js que será o componente Contador:

 import React from 'react';
 import ReactDOM from 'react-dom';
 import {connect} from 'react-redux';
 import {bindActionCreators} from 'redux';
 import {somarAction} from './ContadorActions';
 
 class Contador extends React.Component{
 
     _somar() {
         this.props.somarAction(this.props.valorAtual);
     }    
     
      render(){
         return (
             <div>
                 <h1>React com Redux</h1>
                 <button onClick={this._somar.bind(this)}>Somar</button>
                 <span>{this.props.valorAtual}</span>
             </div> 
         )
      }
 }
 
  function mapStateToProps(state){
     return {
         valorAtual: state.contadorReducerChave.valorAtual
     }
  }
  
  function mapDispatchToProps(dispatch){
     return bindActionCreators({somarAction},dispatch);
  }
  
  export default connect(mapStateToProps,mapDispatchToProps)(Contador);

O componente Contador exportado está sendo decorado com mapStateToProps e mapDispatchToProps. Isso significa que as variáveis valorAtual somarAction vão ser passadas automaticamente como props para o Compoente Contador. valorAtual recebe o valor inicial do reducer e somarAction é uma função, a ação que vai ser despachada e evoluir o estado de nossa aplicação. 

Agora vamos criar o arquivo chamado ContadorActions.js com o seguinte conteúdo:

 export const somarAction = (valorAtual) => (
     { type: "SOMAR", valorSomado: valorAtual+1 }
 )

Note que essa função somarAction está chegando como props no componente Contador. Isso acontece por que o componente Contador foi decorado com mapDispatchToProps que por sua vez fez o bindActionCreators passando o somarAction.

Para finalizar, vamos criar nosso reducer no arquivo contadorReducer.js (todos dentro da pasta src/app)

 const INITIAL_STATE = {valorAtual: 0}
 
 export default function(state = INITIAL_STATE,action){
     switch(action.type){
         case 'SOMAR':
             return {...state,valorAtual: action.valorSomado};
         default:
             return state;
     }
 }

Agora ficou fácil entender que o valorSomado definido na action foi passado via dispatch para o reducer que evolui o estado. Feito isso, o componente é automaticamente renderizado e finaliza-se o cículo de vida Redux. 

Se estiver tudo certo, ao clicar no botão Somar o valor ao lado é atualizado:

Imagem

Comentários

 

Quem Sou

Graduado em ADS (Análise e desenvolvimento de sistemas).

Não sou "devoto" de nenhuma linguagem de programação. Procuro aproveitar o melhor de cada uma de acordo com a necessidade do projeto. Prezo por uma arquitetura bem feita, código limpo, puro e simples! 

anuncio atendente