280 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
		
		
			
		
	
	
			280 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
|   | --- | |||
|  | title: React Redux Basic Setup | |||
|  | localeTitle: React Redux Basic Setup | |||
|  | ---
## React Redux Basic Setup
 | |||
|  | 
 | |||
|  | Neste guia, será apresentado ao leitor como configurar um aplicativo simples React e Redux. | |||
|  | 
 | |||
|  | Baseia-se no princípio de que um aplicativo [Node.js](https://nodejs.org/) já está criado e sendo executado com o [Express](https://expressjs.com/) e o [Webpack](https://webpack.github.io/) . | |||
|  | 
 | |||
|  | ## Instalação
 | |||
|  | 
 | |||
|  | Assumindo que tudo esteja configurado e funcionando corretamente, existem alguns pacotes que precisam ser adicionados para que o Redux funcione com o React. | |||
|  | 
 | |||
|  | Abra um terminal dentro da pasta do projeto que foi criada e emita o seguinte comando | |||
|  | 
 | |||
|  | ```sh | |||
|  | npm install --save react react react-dom react-redux react-router redux  | |||
|  | ``` | |||
|  | 
 | |||
|  | O que o comando acima faz é instalar os pacotes localmente e adicionar uma referência ao arquivo package.json nas dependências. | |||
|  | 
 | |||
|  | Também adicione ao seu navegador de escolha a seguinte ferramenta [Redux Dev Tools](https://github.com/zalmoxisus/redux-devtools-extension) . | |||
|  | 
 | |||
|  | Isso permitirá que o desenvolvedor veja o estado do aplicativo e suas alterações e quais ações estão sendo acionadas também. | |||
|  | 
 | |||
|  | ## Estrutura de pastas
 | |||
|  | 
 | |||
|  | Com todas as dependências instaladas, é altamente recomendável criar uma estrutura de pastas dentro de seu aplicativo, semelhante a uma abaixo, para melhor manutenção e organização do código. | |||
|  | ``` | |||
|  | project_root  | |||
|  |  │   index.js  | |||
|  |  |  | |||
|  |  └───client  | |||
|  |  |   App.jsx  | |||
|  |  |   NotFound.jsx  | |||
|  |  |  | |||
|  |  └───common  | |||
|  |     │  | |||
|  |     └───actions  | |||
|  |     |   │  appActions.js  | |||
|  |     |  | |||
|  |     └───constants  | |||
|  |     |   │  Actiontypes.js  | |||
|  |     |  | |||
|  |     └───reducers  | |||
|  |     |   │   appReducer.js  | |||
|  |     └───store  | |||
|  |         │   store.js  | |||
|  | ``` | |||
|  | 
 | |||
|  | ## Descrição dos componentes do aplicativo e como eles interagem entre si e com o redux
 | |||
|  | 
 | |||
|  | ## Implementação do ponto de entrada do aplicativo
 | |||
|  | 
 | |||
|  | *   /project\_root/index.js | |||
|  |     *   É o ponto de entrada para o aplicativo que irá conter o ponto de entrada para qual loja, e irá processar o arquivo App.jsx. | |||
|  | 
 | |||
|  | Abaixo está um exemplo do código que será declarado no arquivo | |||
|  | 
 | |||
|  | ```javascript | |||
|  | import React from 'react';  | |||
|  |  import {render} from 'react-dom';  | |||
|  |  import {Router,Route,browserHistory} from 'react-router';  | |||
|  |  import {Provider} from "react-redux";  | |||
|  |  import store from "../common/store/store";  | |||
|  |  import App from '../client/App';  | |||
|  |  import NotFound from '../client/notFound';  | |||
|  |   | |||
|  |  render(  | |||
|  |     <Provider store={store}>  | |||
|  |         <Router history={browserHistory}>  | |||
|  |             <Route path="/" component={App} />  | |||
|  |             <Route path="*" component={NotFound}/>  | |||
|  |         </Router>  | |||
|  |     </Provider>,  | |||
|  |     document.getElementById('root')  | |||
|  |  );  | |||
|  | ``` | |||
|  | 
 | |||
|  | Neste exemplo, as importações de reação usuais são adicionadas ao arquivo, mas também algumas novas, como o Roteador, Rota, browserHistory. | |||
|  | 
 | |||
|  | Esses são responsáveis pelo manuseio de rotas, se elas forem necessárias para o aplicativo. | |||
|  | 
 | |||
|  | E também onde o armazenamento de aplicativos é adicionado e permitido trabalhar no aplicativo. | |||
|  | 
 | |||
|  | ## Implementação de componente de aplicativo
 | |||
|  | 
 | |||
|  | O seguinte arquivo: | |||
|  | 
 | |||
|  | *   /client/App.jsx | |||
|  | *   Este arquivo é o arquivo de aplicativo de linha de base e onde react e redux se comunicarão entre si. | |||
|  | 
 | |||
|  | ```javascript | |||
|  | import React, { Component } from 'react';  | |||
|  |  import {connect} from 'react-redux';  | |||
|  |  import PropTypes from 'prop-types';  | |||
|  |  import {ActionA,ActionB,ActionC} from '../common/actions/appActions';  | |||
|  |  class App extends Component{  | |||
|  |   | |||
|  |     // example of triggering the action inside a component  | |||
|  |     foo=()=>{  | |||
|  |         this.props.doStringMessage(`Hello World`);  | |||
|  |     }  | |||
|  |     //default render function of the component  | |||
|  |     render(){  | |||
|  |         return(  | |||
|  |             // the base component  | |||
|  |         );  | |||
|  |     }  | |||
|  |  }  | |||
|  |  /**  | |||
|  |  * es6 fat arrow function to get information from the application state  | |||
|  |  * @param {*} state current state of the application  | |||
|  |  */  | |||
|  |  const mapStateToProps=state=>{  | |||
|  |     return {  | |||
|  |         ArrayValue:state.example.exapleArray,  | |||
|  |         StringMessage:state.example.exampleString,  | |||
|  |         bookApploggedIn:state.example.exampleBool,  | |||
|  |         ObjectValue:state.example.exampleObject  | |||
|  |     };  | |||
|  |  };  | |||
|  |  /**  | |||
|  |  * es6 fat arrow function to connect the actions declared in the action file to the the component as if they were common react props  | |||
|  |  * @param {*} dispatch function send to action file to be later processed in the reducer  | |||
|  |  */  | |||
|  |  const mapDispatchToProps=dispatch=>{  | |||
|  |     return {  | |||
|  |         doStringMessage:(value)=>{  | |||
|  |             dispatch(ActionA(value));  | |||
|  |         },  | |||
|  |         getArrayItems:()=>{  | |||
|  |             dispatch(ActionB());  | |||
|  |         },  | |||
|  |         doBooleanChange:(value)=>{  | |||
|  |             dispatch(ActionC(value));  | |||
|  |         }  | |||
|  |     };  | |||
|  |  };  | |||
|  |  /**  | |||
|  |  * this function connects the application component to be possible to interact with the store  | |||
|  |  * @param {*} mapStateToProps allows the retrieval of information from the state of the application  | |||
|  |  * @param {*} mapDispatchToProps allows the state to change via the actions defined inside  | |||
|  |  */  | |||
|  |  export default connect(mapStateToProps,mapDispatchToProps)(App);  | |||
|  | ``` | |||
|  | 
 | |||
|  | O exemplo acima demonstra como o componente base do aplicativo é configurado e como ele irá interagir com a arquitetura do redux. | |||
|  | 
 | |||
|  | Também como despachar uma ação definida do componente que será passada para o armazenamento e fazer as alterações no redutor do aplicativo. | |||
|  | 
 | |||
|  | ## Declaração das Ações de Aplicação
 | |||
|  | 
 | |||
|  | O seguinte arquivo: | |||
|  | 
 | |||
|  | *   /common/actions/appActions.js | |||
|  |      | |||
|  | *   Este arquivo é onde cada uma das ações definidas irá interagir com o estado da aplicação e com o redutor. | |||
|  |      | |||
|  | *   E também qualquer chamada de API externa necessária para o aplicativo deve ser feita aqui e depois passada para o redutor através da chamada de uma ação. | |||
|  |      | |||
|  |     \`\` \`javascript importar { APP _AÇÃO_ A, APP _ACTION_ B, APP _ACTION_ C } de '../constants/Actiontypes'; / \*\* | |||
|  |      | |||
|  | *   es6 constante para comunicar com redutor para realizar uma determinada ação | |||
|  |      | |||
|  | *   @param {Object} valoriza um objeto ou qualquer outro tipo a ser definido no redutor **/ export const doActionA = value => ({ tipo: APP _AÇÃO_ A, valor }); /** | |||
|  |      | |||
|  | *   es6 constante para comunicar com redutor para realizar uma determinada ação | |||
|  |      | |||
|  | *   @param {Object} um objeto ou qualquer outro tipo a ser definido no redutor **/ export const doActionB = value => ({ tipo: APP _ACTION_ B, valor }); /** | |||
|  |      | |||
|  | *   es6 constante para comunicar com redutor para realizar uma determinada ação | |||
|  |      | |||
|  | *   @param {Object} um objeto ou qualquer outro tipo a ser definido no redutor **/ export const doActionC = value => ({ tipo: APP _ACTION_ C, valor }); /** | |||
|  |      | |||
|  | *   es6 constante que será conhecida pelo componente para que seja possível a interação entre o componente e o estado | |||
|  |      | |||
|  | *   @param {Object} valoriza um objeto ou qualquer outro tipo a ser definido no redutor **/ exportar const ActionA = value => dispatch => { despacho (doActionB (valor)); }; /** | |||
|  |      | |||
|  | *   es6 constante que será conhecida pelo componente para que seja possível a interação entre o componente e o estado \*\* / exportar const ActionB = () => dispatch => { expedição (doActionB (true)); }; `In the example code provided above, the item` ActionB\`\`\` será disponibilizado para o componente App.jsx e quando for acionado pelo componente por meio de um prop, ele acionará a ação apropriada dentro desse arquivo e, em seguida, para o redutor e alterará o declarar em conformidade. | |||
|  |      | |||
|  | 
 | |||
|  | ## Implementação de tipos de ação
 | |||
|  | 
 | |||
|  | O seguinte arquivo: | |||
|  | 
 | |||
|  | *   /common/constants/Actiontypes.js | |||
|  | *   Este arquivo conterá a declaração de cada um dos tipos de ações disponíveis para serem usados pelo aplicativo. | |||
|  | *   As declarações feitas aqui terão que disponibilizar o arquivo de ações para que elas sejam manipuladas no aplicativo. | |||
|  | 
 | |||
|  | ```javascript | |||
|  | export const APP_ACTION_A='MAKE_A';  | |||
|  |  export const APP_ACTION_B='MAKE_B';  | |||
|  |  export const APP_ACTION_C='MAKE_C';  | |||
|  | ``` | |||
|  | 
 | |||
|  | No exemplo acima, três tipos de ações são declarados e exportados para serem disponibilizados para serem consumidos. | |||
|  | 
 | |||
|  | ## Implementação do redutor
 | |||
|  | 
 | |||
|  | O seguinte arquivo: | |||
|  | 
 | |||
|  | *   /common/reducers/appReducer.js | |||
|  |     *   O redutor, em essência, nada mais é do que uma função pura de javascript que irá verificar se alguma das condições atende a ação desencadeada e faz as alterações no estado, nunca alterando-a. | |||
|  | 
 | |||
|  | ```javascript | |||
|  |  import {  | |||
|  |     APP_ACTION_A,  | |||
|  |     APP_ACTION_B,  | |||
|  |     APP_ACTION_C  | |||
|  |  } from '../constants/Actiontypes';  | |||
|  |   | |||
|  |  /**  | |||
|  |  * es6 example of a declaration of the reducer  | |||
|  |  * @param {Object} state contains all the application's state properties needed  | |||
|  |  * @param {action} action the action that will trigger the state's changes  | |||
|  |  **/  | |||
|  |  const ExampleAppReducer= (state = {  | |||
|  |     exampleBool:false, // boolean value  | |||
|  |     exampleString:'', // string value  | |||
|  |     exampleArray: [], // array value  | |||
|  |     onError:{  | |||
|  |         A:'',  | |||
|  |         B:'',  | |||
|  |         C:''  | |||
|  |     } // object with properties inside  | |||
|  |  }, action) => {  | |||
|  |     //switch statement that will test every case and make the necessary changes, never mutating the state as it's being preserved always  | |||
|  |     switch(action.type){  | |||
|  |         case APP_ACTION_A:{  | |||
|  |             return {  | |||
|  |                 ...state, // es6 epread operator to make a copy of the existing state object  | |||
|  |                 exampleBool:action.value // the state property changes accordingly to the value of the action triggered  | |||
|  |             };  | |||
|  |         }  | |||
|  |         case APP_ACTION_B:{  | |||
|  |             return {  | |||
|  |                 ...state,  | |||
|  |                 exampleString:action.value  | |||
|  |             };  | |||
|  |         },  | |||
|  |         case APP_ACTION_C:{  | |||
|  |             return {  | |||
|  |                 ...state,  | |||
|  |                 exampleArray:action.value  | |||
|  |             };  | |||
|  |         }  | |||
|  |         default:{  | |||
|  |             return state; // if any of the actions triggered is not defined here it will return the default state  | |||
|  |         }  | |||
|  |     }  | |||
|  |  };  | |||
|  |  export default ExampleAppReducer;  | |||
|  | ``` | |||
|  | 
 | |||
|  | O código acima ilustra como um redutor básico é definido e faz alterações no estado, através do teste de uma determinada condição. | |||
|  | 
 | |||
|  | ## Implementação de loja
 | |||
|  | 
 | |||
|  | O arquivo: | |||
|  | 
 | |||
|  | *   /common/store/store.js | |||
|  | *   Este arquivo irá conter a definição da árvore de estados do aplicativo, a fim de alterar o estado interno, uma ação precisa ser enviada para aqui. | |||
|  | *   Não é nada mais do que um objeto com métodos declarados dentro, o mais importante para criar a loja | |||
|  | 
 | |||
|  | \`\` \`javascript import {createStore} de 'redux'; import example from '../reducers/ExampleAppReducer'; | |||
|  | 
 | |||
|  | createStore padrão de exportação ( exemplo ); \`\` \` O código acima demonstra como definir um armazenamento de aplicativo simples. | |||
|  | 
 | |||
|  | Esta é a configuração básica de um redutor, ele pode ser expandido ainda mais e conter várias lojas, por exemplo, e também ter alguns middlewares adicionados a ele. | |||
|  | 
 | |||
|  | ## Leitura adicional
 | |||
|  | 
 | |||
|  | Como este guia nada mais é do que uma introdução sobre como o reagir e o redux funcionam juntos e como implementar a arquitetura. É altamente recomendável que o leitor deste guia leia os links abaixo para ler e clonar os repositórios e testá-los. | |||
|  | 
 | |||
|  | [Redux Docs](http://redux.js.org/) | |||
|  | 
 | |||
|  | [Redux Api](http://redux.js.org/docs/api/) | |||
|  | 
 | |||
|  | [Exemplos de Redux](https://github.com/reactjs/redux/tree/master/examples) |