use*_*079 3 react-native redux rxjs5 react-redux redux-observable
当我getCurrentPositionEpic在以下代码中注释掉时,该应用程序正常运行。但是,如果我不加注释,则会出现错误:
动作必须是普通对象。使用自定义中间件进行异步操作。
export const rootEpic = combineEpics(
fetchCategoriesEpic,
getCurrentLocationEpic,
getCurrentPositionEpic
)
const store = createStore(
rootReducer,
initialState,
composeWithDevTools(
applyMiddleware(createEpicMiddleware(rootEpic))
)
)
Run Code Online (Sandbox Code Playgroud)
location.epic.js
const getCurrentPosition$ = getCurrentPositionObservable(
{ enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 }
)
getCurrentPosition$.subscribe(
(position) => {
console.log(position)
const positionObject = {
lat: position.coords.latitude,
lng: position.coords.longitude
}
//store.dispatch(updateRegion(positionObject))
//getCurrentLocation(positionObject)
},
(err) => {
console.log('Error: %s', err)
},
() => {
console.log('Completed')
})
export const getCurrentLocationEpic = action$ =>
action$.ofType(GET_CURRENT_LOCATION)
.mergeMap(() =>
Observable.fromPromise(Geocoder.geocodePosition(makeSelectLocation()))
.flatMap((response) => Observable.of(
getCurrentLocationFulfilled(response)
))
.catch(error => Observable.of(getCurrentLocationRejected(error)))
)
export const getCurrentPositionEpic = action$ =>
action$.ofType(GET_CURRENT_POSITION)
.mapTo(() => getCurrentPosition$
.flatMap((response) => Observable.of(
getCurrentPositionFulfilled(response)
))
.catch(error => Observable.of(getCurrentLocationRejected(error)))
)
Run Code Online (Sandbox Code Playgroud)
下面的代码只是一个用于将本机反应转换navigator.geolocation.getCurrentPosition为可观察反应的助手,而不是用于执行回调的函数。
callBackToObservable.js
import { Observable } from 'rxjs'
export const getCurrentPositionObservable = Observable.bindCallback(
(options, cb) => {
if (typeof options === 'function') {
cb = options
options = null
}
navigator.geolocation.getCurrentPosition(cb, null, options)
})
Run Code Online (Sandbox Code Playgroud)
是什么导致错误?
尝试通过商店:
export const getCurrentPositionFulfilledEpic = (action$, store) =>
action$.ofType(GET_CURRENT_POSITION_FULFILLED)
.mergeMap(() =>{
console.log(store)***************** store is populated here
return Observable.fromPromise(Geocoder.geocodePosition({
lat: store.getState().get('searchForm').get('position').lat,***but not here
lng: store.getState().get('searchForm').get('position').lng
}))
.flatMap((response) => Observable.of(
getCurrentLocationFulfilled(response)
))
.catch(error => Observable.of(getCurrentLocationRejected(error)))
}
)
Run Code Online (Sandbox Code Playgroud)
使用https://github.com/devfd/react-native-geocoder用于Geocoder.geocodePosition
问题是您使用mapTo。您基本上是在说“将此动作映射到一个Observable”,所以现在您的史诗返回的是Observable of Observable动作,Observable<Observable<Action>>而不只是一个Observable动作。
换句话说,您的史诗现在正在发出Observables而不是发出动作。你不是需要使用并购战略运营商一样mergeMap,switchMap等合并扁平化/内可观测链合并成顶级之一。flatMap是的别名mergeMap,顺便说一句。
export const getCurrentPositionEpic = action$ =>
action$.ofType(GET_CURRENT_POSITION)
.mergeMap(() => getCurrentPosition$
.flatMap((response) => Observable.of(
getCurrentPositionFulfilled(response)
))
.catch(error => Observable.of(getCurrentLocationRejected(error)))
)
Run Code Online (Sandbox Code Playgroud)
另一件事-您无需使用flatMapaka mergeMap将其映射getCurrentPosition$到getCurrentPositionFulfilled动作,因为它是1:1。如果是一对多,则只需要它。
export const getCurrentPositionEpic = action$ =>
action$.ofType(GET_CURRENT_POSITION)
.mergeMap(() => getCurrentPosition$
.map((response) => getCurrentPositionFulfilled(response))
.catch(error => Observable.of(getCurrentLocationRejected(error)))
)
Run Code Online (Sandbox Code Playgroud)
以您的方式使用它并没有真正的危害,但是可能会使以后维护代码的其他人感到困惑。
| 归档时间: |
|
| 查看次数: |
967 次 |
| 最近记录: |