从 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}¤cy=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}¤cy=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);
}
我寻求有关 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}¤cy=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}¤cy=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);
}