从 Redux-thunk 重构为 Redux-saga (+axios)

Refactoring from Redux-thunk to Redux-saga (+axios)

我寻求有关 Redux-saga 的帮助,即重构下面的代码。欢迎任何想法或解释。下面的代码使用函数的参数根据请求从 API 中获取酒店列表。它还可以检查当前是否正在加载数据或根本没有加载数据。如果接收到数据,则成功执行操作创建者集酒店。预先感谢您的回复。

hotels.js

export const getHotels = (cityName = 'London', date = currentDate(), days = 1, limit = 30) => {
return async (dispatch) => {
    dispatch(setIsFetching(true))
    dispatch(setIsEmpty(false))
    try {
        const response = await axios.get(`http://engine.hotellook.com/api/v2/cache.json?location=${cityName}&currency=rub&checkIn=${date}&checkOut=${addDays(date, days)}&limit=${limit}`)
        response.data.length === 0 ? dispatch(setIsEmpty(true)) : dispatch(setHotels(response.data))
    }
    catch (e) {
        dispatch(setIsEmpty(true))
    }
}

hotelsReducer.js

const SET_HOTELS = "SET_HOTELS";
const SET_IS_FETCHING = "SET_IS_FETCHING";
const SET_IS_EMPTY = "SET_IS_EMPTY";

const defaultState = {
  hotels: [],
  isFetching: true,
  isEmpty: false,
};

export const hotelsReducer = (state = defaultState, action) => {
  switch (action.type) {
    case SET_HOTELS:
      return {
        ...state,
        hotels: action.payload,
        isFetching: false,
      };
    case SET_IS_FETCHING:
      return {
        ...state,
        isFetching: action.payload,
      };
    case SET_IS_EMPTY:
      return {
        ...state,
        isEmpty: action.payload,
      };
    default:
      return state;
  }
};

export const setHotels = (results) => {return { type: SET_HOTELS, payload: results }};
export const setIsFetching = (bool) => {return { type: SET_IS_FETCHING, payload: bool }};
export const setIsEmpty = (bool) => {return { type: SET_IS_EMPTY, payload: bool }};

传奇将非常相似,您只需将 thunk 替换为将触发传奇的新动作:

import { put, takeLatest } from "redux-saga/effects";

function* fetchHotelsSaga() {
  yield put(setIsFetching(true));
  yield put(setIsEmpty(false));
  try {
    const response = yield axios.get(`http://engine.hotellook.com/api/v2/cache.json?location=${cityName}&currency=rub&checkIn=${date}&checkOut=${addDays(date, days)}&limit=${limit}`);
    response.data.length === 0
      ? yield put(setIsEmpty(true))
      : yield put(setHotels(response.data));
  } catch (e) {
    yield put(setIsEmpty(true));
  }
}

function* hotelsSaga() {
  // FETCH_HOTELS is a type for the new action that will be dispatched instead of the thunk
  yield takeLatest(FETCH_HOTELS, fetchHotelsSaga);
}