Redux no React - Assíncrono
Gabriel_Silvestre
Posted on January 6, 2022
Redux Thunk
O que é?
É um pacote complementar do Redux que permite a execução de código assíncrono, para o armazenamento e manipulação de estados. Esse pacote é necessário, pois normalmente o Redux aceita apenas código 100% síncrono.
Instalando
Por se tratar de um pacote complementar, ele não vem instalado junto ao Redux, porém para instalá-lo é muito simples, basta utilizar o comando:
npm i redux-thunk
Não sendo necessário nenhuma configuração adicional.
Aplicando Redux-Thunk no Redux
Para termos acesso às funcionalidades assíncronas, precisamos passar um segundo parâmetro para a função createStore()
, que é outra função chamada applyMiddleware()
, que por sua vez recebe o thunk do Redux-Thunk como parâmetro.
const store = createStore(rootReducer, applyMiddleware(thunk));
Redux-Thunk Actions
Sintaxe
A sintaxe de uma Action Creator assíncrona, possibilitada pelo Redux-Thunk, consiste em uma função que retorna outra função, essa que recebe o dispatch como parâmetro padrão.
function asyncAction() {
return (dispatch) => {};
}
Em geral a sintaxe é a do exemplo acima, porém podemos “incrementar” a Action Creator o quanto quisermos, desde que ela retorne ao final um objeto no formato esperado pelo Reducer.
function fetchData() {
return (dispatch) => {
dispatch(startRequest());
return fetch(<API endpoint>)
.then((res) => res.json()
.then(
(data) => dispatch(getData(data)),
(error) => dispatch(getError(error)),
));
};
}
No exemplo acima temos uma função que pode disparar três Actions, sendo elas respectivamente startRequest()
, getData()
e getError()
. O nome dado no exemplo é genérico, porém em funções de requisição à API não é incomum que tenhamos exatamente essas três Actions, porém com nomes mais apropriados.
startRequest
A startRequest()
é uma Action que tem como função alterar o estado de “loading” da aplicação, assim podemos realizar renderizações condicionais como fazíamos sem usar o Redux.
const startRequest = () => ({ type: START_REQUEST });
getData
A getData()
, como o nome dá a entender, é uma Action que irá salvar em nosso estado os dados recebidos da API, sendo necessário preparar o Reducer para os diferentes tipos de dados.
const getData = (payload) => ({ type: GET_DATA, payload });
getError
E por fim a getError()
é uma Action que irá armazenar o erro de requisição em nosso estado, isso se houver um erro.
const getError = (payload) => ({ type: GET_ERROR, payload });
Exemplo de Reducer
Abaixo será mostrado um Reducer genérico de acordo com a função e as actions exemplificadas acima.
Já adiantando que a estrutura base continuará sendo a mesma.
const INITIAL_STATE = {
data: [],
error: undefined,
loading: false,
}
export default function myReducer(state = INITIAL_STATE, action) {
switch (action.type) {
case START_REQUEST:
return {
...state,
loading: true,
}
case GET_DATA:
return {
...state,
data: action.payload,
loading: false,
}
case GET_ERROR:
return {
...state,
error: action.payload,
loading: false,
}
default:
return state;
}
}
No Reducer acima temos três casos, o primeiro apenas altera a chave loading
, indicando que uma requisição foi iniciada, já o segundo e terceiro caso, além de alterarem novamente a chave loading
, para indicar que a requisição foi concluída, também armazenam a resposta dessa requisição, seja ela dados ou erros (respectivamente).
E o resto?
O resto da estrutura base do Redux (reducers, store, Provider e actions síncronas) continuem funcionando exatamente como antes.
Posted on January 6, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.