使用 redux-saga 获取位置并触发基于位置的请求
Getting location and fire a location based request with redux-saga
我不太了解 redux-saga 如何帮助我管理副作用,需要一些解释。
这是我的案例:
我正在构建一个反应本机应用程序,它必须在到达第一个屏幕时触发基于位置的 API 请求,在获取时显示加载并在获取结果时显示结果。
现在我有 2 个减速器:设备和餐厅
DeviceRedux.js
像这样存储位置的状态:
{
locationPermission: 'authorized', // one of 'authorized', 'denied', 'restricted' or 'undetermined'
locationActive: true, // if locations services are turned on or not
locationError: '',
lastLocation: {
lat: 12.3456,
lng: 65.4321,
date: '2019-22-01T12:30:00.000+01:00,
},
fetchingLocation: false,
}
RestaurantsRedux.js
像这样存储餐厅的状态:
{
restaurantsList: [{
name: 'Pizza for You',
id: '123-oer-432',
}, ...]
fetchingRestaurants: false,
}
和 2 个传奇:
DeviceSagas.js
处理有关位置的传奇故事
export function* getCurrentLocationSaga(action) {
// check locations
const locationPermission = yield call(checkLocationPermission);
// save locationPermission in redux state
yield put(DeviceRedux.setLocationPermission(locationPermission));
switch (locationPermission) {
case 'authorized'
// 1 check if location service is enabled
// 2 if enabled retrieve location and save it to redux store
// handle all other possibilities
}
}
async function checkLocationPermission() {
try {
const response = await Permissions.check('location');
return response;
} catch (error) {
console.log('ERROR while checking location permission', error);
return 'denied';
}
}
RestaurantsSagas.js
处理有关餐厅的传奇故事
export function* getRestaurantsByPosition(api, action) {
const {
position,
} = action;
const response = yield call(api.getRestaurantsByPostion, position);
if (response.ok) {
yield put(RestaurantsActions.restaurantsByPositionSuccess(response.data));
} else {
yield handleError(response)
}
}
我想制作一个新的 saga,启动 getCurrentLocationSaga
并等待它在新位置完成,当获得新位置时,然后开始新的餐厅搜索。我该怎么做?
您可以使用 take
to pull future actions:
function* watchFetchLocationsAndRestourants(action) {
yield call(getCurrentLocationSaga, action);
// wait for: 2 if enabled retrieve location and save it to redux store
const foundLocationsAction = yield take('SAVE_LOCATIONS_TO_REDUX');
const restaurants = yield call(getRestaurantsByPosition, api, {payload: foundLocationsAction.locations, type: 'YOUR_TYPE'});
}
所以你开始获取当前位置,saga 仅在 SAVE_LOCATIONS_TO_REDUX
调度时继续执行。接下来,您将使用您获得的位置调用餐厅搜索。
我不太了解 redux-saga 如何帮助我管理副作用,需要一些解释。
这是我的案例:
我正在构建一个反应本机应用程序,它必须在到达第一个屏幕时触发基于位置的 API 请求,在获取时显示加载并在获取结果时显示结果。
现在我有 2 个减速器:设备和餐厅
DeviceRedux.js
像这样存储位置的状态:
{
locationPermission: 'authorized', // one of 'authorized', 'denied', 'restricted' or 'undetermined'
locationActive: true, // if locations services are turned on or not
locationError: '',
lastLocation: {
lat: 12.3456,
lng: 65.4321,
date: '2019-22-01T12:30:00.000+01:00,
},
fetchingLocation: false,
}
RestaurantsRedux.js
像这样存储餐厅的状态:
{
restaurantsList: [{
name: 'Pizza for You',
id: '123-oer-432',
}, ...]
fetchingRestaurants: false,
}
和 2 个传奇:
DeviceSagas.js
处理有关位置的传奇故事
export function* getCurrentLocationSaga(action) {
// check locations
const locationPermission = yield call(checkLocationPermission);
// save locationPermission in redux state
yield put(DeviceRedux.setLocationPermission(locationPermission));
switch (locationPermission) {
case 'authorized'
// 1 check if location service is enabled
// 2 if enabled retrieve location and save it to redux store
// handle all other possibilities
}
}
async function checkLocationPermission() {
try {
const response = await Permissions.check('location');
return response;
} catch (error) {
console.log('ERROR while checking location permission', error);
return 'denied';
}
}
RestaurantsSagas.js
处理有关餐厅的传奇故事
export function* getRestaurantsByPosition(api, action) {
const {
position,
} = action;
const response = yield call(api.getRestaurantsByPostion, position);
if (response.ok) {
yield put(RestaurantsActions.restaurantsByPositionSuccess(response.data));
} else {
yield handleError(response)
}
}
我想制作一个新的 saga,启动 getCurrentLocationSaga
并等待它在新位置完成,当获得新位置时,然后开始新的餐厅搜索。我该怎么做?
您可以使用 take
to pull future actions:
function* watchFetchLocationsAndRestourants(action) {
yield call(getCurrentLocationSaga, action);
// wait for: 2 if enabled retrieve location and save it to redux store
const foundLocationsAction = yield take('SAVE_LOCATIONS_TO_REDUX');
const restaurants = yield call(getRestaurantsByPosition, api, {payload: foundLocationsAction.locations, type: 'YOUR_TYPE'});
}
所以你开始获取当前位置,saga 仅在 SAVE_LOCATIONS_TO_REDUX
调度时继续执行。接下来,您将使用您获得的位置调用餐厅搜索。