Redux
Uso do Redux
Instalação
Instalação do Redux no React
$ yarn add redux react-redux
Configuração
Arquivo /src/store/index.js
import { createStore } from 'redux';const store = createStore();export default store;
Arquivo src/App.js
Importação do Provider do react-redux e do método store criado anteriormente
import { Provider } from 'react-redux';import store from './store';
Envolver todos os componentes com o método Provider passando o atributo store
function App() {return (<Provider store={store}><BrowserRouter><Header /><Routes /><GlobalStyle /></BrowserRouter></Provider>);}
ATENÇÃO!
O arquivo src/store/index.js necessita de um reducer para funcionar.
Criação do Reducer em src/store/modules/cart/reducer.js
export default function cart() {return [];}
Exemplo do arquivo store com com um Reducer
import { createStore } from 'redux';import reducer from './modules/cart/reducer';const store = createStore(reducer);export default store;
Múltiplos reducers
Arquivo src/store/modules/rootReducer.js
import { combineReducers } from 'redux';import cart from './cart/reducer';export default combineReducers({cart,});
Arquivo src/store/index.js
import { createStore } from 'redux';import rootReducer from './modules/rootReducer';const store = createStore(rootReducer);export default store;
Conexões e Uso Prático
Importação em uma página com componentes
Importação do connect do react-redux
import { connect } from 'react-redux';
Novo modelo de exportação
export default connect()(Home);
Adicionando uma action em um componente
O botão:
<buttontype="button"onClick={() => this.handleAddProduct(product)}>
A função handleAddProduct():
handleAddProduct = product => {const { dispatch } = this.props;dispatch({type: 'ADD_TO_CART', // O dispatch é quem dispara a função e é acessível graças ao connectproduct,});};
O reducer:
export default function cart(state = [], action) { // Estado inicial e a ação executada como parâmetroswitch (action.type) {case 'ADD_TO_CART': // Reducer sendo chamado apenas caso seja o ADD_TO_CARTreturn [...state, action.product]; // Retornando o estado inicial + o produto chamado naquela actiondefault:return state; // Reducer ignorando outras actions que não sejam pertinentes}}
Recebendo estado de outros componentes
Exemplo de um cabeçalho de e-commerce.
Importação do connect
import { connect } from 'react-redux';
Passando um objeto na função para conectá-lo com o componente
function Header({ cart }) {return (...)}
Exportar com o connect passando o estado como um objeto
export default connect(state => ({cart: state.cart, // O cart de "state.cart" é o cart declarado no rootReducer}))(Header);
MapStateToProps
Recebe o estado da aplicação e adiciona uma propriedade. Exemplo:
const mapStateToProps = state => ({cart: state.cart,});
A função deve se parecer com:
function Cart({ cart }) {...}
Exportação:
export default connect(mapStateToProps)(Cart);
MapDispatchToProps
Faz o disparo de uma action e armazena nas propriedades do estado da aplicação.
const mapDispatchToProps = dispatch =>bindActionCreators(CartActions, dispatch);
O bindActionCreators
é importado do redux e o CartActions segue o modelo exemplificado na sessão 5.1.
Exportação:
export default connect(mapStateToProps, mapDispatchToProps)(Cart); // Caso não possua StateToProps, deve ser passado um valor sendo "null"
bindActionCreators
O bindActionCreators serve para organizar melhor o dispatch de actions. Sua importação vem do Redux
import bindActionCreators from 'redux';
É uma função que recebe como primeiro parâmetro as actions e o segundo dispatch:
const mapDispatchToProps = dispatch =>bindActionCreators(CartActions, dispatch);
Organização de Actions
Exemplo de um arquivo em src/store/modules/cart/actions
Aqui pode ser organizado todas as actions que anteriormente eram enviadas através de uma função dentro do próprio componente.
export function addToCart(product) {return {type: '@cart/ADD',product,};}export function removeFromCart(id) {return { type: '@cart/REMOVE', id };}export function updateAmount(id, amount) {return {type: '@cart/UPDATE_AMOUNT',id,amount,};}
Utilização
Nos exemplos acima são utilizados essas actions com o nome 'CartActions'
Importação
import * as CartActions from '../../store/modules/cart/actions';
Dentro dos parâmetros da função, são passadas as actions existentes no arquivo actions.js que necessitam ser usadas (funções exemplificadas acima):
function Cart({ cart, removeFromCart, updateAmount }) {...}