Redux - Middleware
O próprio Redux é síncrono, então como o async operações como network requesttrabalhar com Redux? Aqui, os middlewares são úteis. Conforme discutido anteriormente, os redutores são o local onde toda a lógica de execução é escrita. O redutor não tem nada a ver com quem o executa, quanto tempo está levando ou registrando o estado do aplicativo antes e depois da ação ser despachada.
Nesse caso, a função de middleware Redux fornece um meio para interagir com a ação despachada antes que cheguem ao redutor. As funções de middleware personalizadas podem ser criadas escrevendo funções de alta ordem (uma função que retorna outra função), que envolve alguma lógica. Vários middlewares podem ser combinados para adicionar novas funcionalidades, e cada middleware não requer nenhum conhecimento do que veio antes e depois. Você pode imaginar middlewares em algum lugar entre ação despachada e redutor.
Normalmente, middlewares são usados para lidar com ações assíncronas em seu aplicativo. Redux fornece uma API chamada applyMiddleware que nos permite usar middleware customizado, bem como middlewares Redux como redux-thunk e redux-promessa. Aplica middlewares para armazenar. A sintaxe de uso da API applyMiddleware é -
applyMiddleware(...middleware)
E isso pode ser aplicado à loja da seguinte forma -
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers/index';
const store = createStore(rootReducer, applyMiddleware(thunk));
Middlewares permitem que você escreva um despachante de ação que retorna uma função em vez de um objeto de ação. O exemplo para o mesmo é mostrado abaixo -
function getUser() {
return function() {
return axios.get('/get_user_details');
};
}
O envio condicional pode ser escrito dentro do middleware. Cada middleware recebe o despacho da loja para que possam despachar uma nova ação e funções getState como argumentos para que possam acessar o estado atual e retornar uma função. Qualquer valor de retorno de uma função interna estará disponível como o valor da própria função de despacho.
A seguir está a sintaxe de um middleware -
({ getState, dispatch }) => next => action
A função getState é útil para decidir se novos dados devem ser buscados ou se o resultado do cache deve ser retornado, dependendo do estado atual.
Vejamos um exemplo de função de log de middleware personalizado. Ele simplesmente registra a ação e o novo estado.
import { createStore, applyMiddleware } from 'redux'
import userLogin from './reducers'
function logger({ getState }) {
return next => action => {
console.log(‘action’, action);
const returnVal = next(action);
console.log('state when action is dispatched', getState());
return returnVal;
}
}
Agora aplique o middleware do logger à loja, escrevendo a seguinte linha de código -
const store = createStore(userLogin , initialState=[ ] , applyMiddleware(logger));
Despache uma ação para verificar a ação despachada e o novo estado usando o código abaixo -
store.dispatch({
type: 'ITEMS_REQUEST',
isLoading: true
})
Outro exemplo de middleware onde você pode controlar quando mostrar ou ocultar o carregador é fornecido abaixo. Este middleware mostra o carregador quando você está solicitando qualquer recurso e o oculta quando a solicitação do recurso é concluída.
import isPromise from 'is-promise';
function loaderHandler({ dispatch }) {
return next => action => {
if (isPromise(action)) {
dispatch({ type: 'SHOW_LOADER' });
action
.then(() => dispatch({ type: 'HIDE_LOADER' }))
.catch(() => dispatch({ type: 'HIDE_LOADER' }));
}
return next(action);
};
}
const store = createStore(
userLogin , initialState = [ ] ,
applyMiddleware(loaderHandler)
);