DEV Community

Gabriel_Silvestre
Gabriel_Silvestre

Posted on • Updated on

Redux no React - Assíncrono

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
Enter fullscreen mode Exit fullscreen mode

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));
Enter fullscreen mode Exit fullscreen mode

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) => {};
}
Enter fullscreen mode Exit fullscreen mode

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)),
        ));
  };
}
Enter fullscreen mode Exit fullscreen mode

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 });
Enter fullscreen mode Exit fullscreen mode

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 });
Enter fullscreen mode Exit fullscreen mode

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 });
Enter fullscreen mode Exit fullscreen mode

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;
  }
}
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (0)