Guia passo-a-passo para utilização do React + Redux
- #React
- #Redux
Neste guia serão abordados todos os passos para implementação do redux dentro do react. Não é objetivo deste texto convencer sobre a importância destas ferramentas. O leitor deve ter um conhecimento básico de redux, pois não há uma explicação dos termos, apenas instruções de onde estes devem estar e como são conectados. Se você tiver alguma sugestão por favor entre em contato.
1. Antes de iniciar crie pastas dentro do source (src) que irão conter os arquivos necessários na aplicação, essa boa prática facilita a refatoração e adição de novas funcionalidades.
2. O primeiro passo para habilitar a utilização do Redux no React é importar as dependências (npm install –save redux react-redux) e depois ‘envolver’ toda a aplicação pelo componente <Provider> que faz parte da biblioteca do ‘react-redux’, passando para o mesmo o store, como props. (Obs: Uma boa prática é fazer essa operação no index.js, ao invés do app).
3. O store deve ser criado no caminho src/store/index.js, onde a função createStore é importada do ‘redux’ e recebe os reducers como parâmetro. Geralmente em uma aplicação existe mais de um reducer, logo é interessante importar um ‘rootReducer’ que é a combinação de todos os reducers da aplicação.
O segundo parâmetro no createStore deve ser utilizado quando se deseja utilizar o React Dev Tools, que facilita a visualização dos estados quando a aplicação é carregada no navegador.
4. O rootReducer, que é a combinação de todos os reducers da aplicação deve ser criado no caminho src/reducers/index.js. Neste arquivo são importados os reducers e e estes são combinados em um único reducer que será utilizado na criação da store.
É necessário a importação da função combineReducers do ‘redux’, que recebe como parâmetros todos os reducers que também devem ser importados. A combinação dos reducers deve ser a exportação default deste arquivo.
5. Para utilizar e modificar os estados é necessário a criação dos reducers, que devem ficar no caminho src/reducers. Cada reducer é composto geralmente de um switch que altera o estado de acordo com o type passado pela action ‘chamada’.
Este é um exemplo de um reducer bastante simples, os pontos importantes aqui são:
• é necessário criar um estado inicial para passar para o reducer caso o mesmo não receba o state como parâmetro.
• Dentro do Reducer normalmente é construído um switch com diferentes cases, onde dependendo do ‘type’ passado pela action uma ação será executada.
• Dentro do switch é colocada uma opção ‘default’, caso não haja nenhum case com o ‘type’ recebido, onde o state é retornado sem alterações
• Quando for adicionar ou remover alguma informação do state é necessário inserir os dados do mesmo que não serão modificados, ou seja, eles devem ser espalhados com o spread operator (linha 11) dentro do objeto que será retornado.
• Não é possível alterar o state, devido a sua imutabilide, logo é necessário utilizar métodos que ‘clonem’ o seu conteúdo para inserir ou remover algum item de um array por exemplo
Neste exemplo, caso a action ‘chamada’ tenha o type ‘ADD_CLIENT’, o array de clientes irá receber o novo objeto com os dados do novo cliente e somar aos demais que já estavam presentes na base de dados. Na linha 12 a chave ‘clients’ do state recebe como valor o que já havia no seu conteúdo mais o novo objeto de cliente que foi passado dentro do payload da action. Vale ressaltar que não poderia ser utilzado o método .push, dessa forma foi utilizado o concat que faz algo parecido mas sem ‘mutar’ o state original
6. O último ponto para a criação do redux antes da interação com o react, é a criação das actions, estas devem estar no caminho src/actions. A action é uma função que retorna um objeto, sendo que deve conter pelo menos uma chave que é obrigatória, a chave ‘type’ que vai indicar qual case do switch do reducer correspondente deve ser ‘chamado’.
A action pode passar outras informações/parâmetros para o reducer, geralmente essas informações ficam contidas em uma chave ‘payload’, mas as informações podem ser dispostas de outras formas caso seja necessário.
7. Os passos acima forma necessários para criar a estrutura do redux, a partir desse tópico será abordada a forma como deve ser feita a conexão do redux com o react, para que os componentes possam usar as informações contidas na store.
Dentro do componente react, que deve estar normalmente no caminho src/components devem ser criadas duas funções no final do componente, antes do export, que também será modificado. As funções ‘mapDispatchToProps’ e a função ‘mapStateToProps’. Pense nessas duas funções como uma forma de ‘criar’ props que serão utilizadas pelo componente.
8. A função ‘mapStateToProps’ é utilizada para ‘criar’ props com informações que estão no state e poderão ser utilizadas no componente onde foi criada.
Como pode ser visto na figura acima a função está retornando um objeto que contém duas chaves, cada uma dessas chaves está recebendo um valor que está contido no store. Para acessar o valor de clients por exemplo, basta acessar a props com este nome dentro do componente (this.props.clients). Essa função deve ter como parâmetro o state para que este possa ser acessado.
Um ponto importante para abstrair essa parte do contéudo é pensar que essa função será usada pelo connect (será descrito posteriormente) para criar as props indicadas.
Obs.: Um ponto muito importante a ser observado é que as informações salvas no store são separadas em objetos com o nome de cada reducer, ou seja, para acessar uma informação do store deve-se utilizar a estrutura state.nome-do-reducer.chave-que-contém-a-informação.
9. A função mapDispatchToProps é utilizada para criar props com funções que chamam actions que acionam reducers e consequentemente fazem alterações no store, eu gosto de pensar nessa parte como se fosse algo parecido como o this.setState, mas um tanto quanto mais complexo.
Essa função tem ‘dispatch’ como parâmetro e retorna um objeto, sendo que cada chave contém uma função que aciona um dispatch. O dispatch é a forma como a action é chamada para ativar o reducer. Cada uma das chaves criadas aqui estarão disponíveis para serem usadas também como uma props, ou seja, para usar a função ‘addClient’ basta acessar a props com este nome e passar o objeto de newClient como parâmetro (this.props.addClient(newClient)).
10. Por fim o componente deve ser exportado utilizando a função ‘connect’ do ‘react-redux’. Primeiramente devem ser importados a função connect e a action que será utilizada (a action só é necessária se algum state for modificado, ou seja, caso seja criada a função mapStateToProps).
Para usar o connect a seguinte estrutura deve ser utilizada
O connect recebe dois blocos de parâmetro, o primeiro com as funções para a criação das props e o segundo com o componente que está sendo criado. Caso o componente não faça alterações nos estados, basta passar apenas o mapStateToProps. Se o componente não precisar de valores contidos no state, for apenas fazer alterações, deve-se passar apenas o mapDispatchToProps, mas como este deve ser o segundo parâmetro do primeiro bloco, o primeiro parâmetro deve ser null.
Pronto, este é o passo-a-passo de como utilizar react com redux, agora é só utilizar as props criadas dentro dos componentes. Essa é uma primeira versão deste documento, futuramente haverá uma versão mais completa.