React native redux可观察操作必须是普通对象。使用自定义中间件进行异步操作
当我在下面的代码中注释掉React native redux可观察操作必须是普通对象。使用自定义中间件进行异步操作,react-native,redux,react-redux,rxjs5,redux-observable,React Native,Redux,React Redux,Rxjs5,Redux Observable,当我在下面的代码中注释掉getCurrentPositionEpic时,应用程序工作正常。但如果不加注释,则会出现错误: 动作必须是普通对象。使用自定义中间件进行异步 行动 location.epic.js const getCurrentPosition$ = getCurrentPositionObservable( { enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 } ) getCurrentPosition$.
getCurrentPositionEpic
时,应用程序工作正常。但如果不加注释,则会出现错误:
动作必须是普通对象。使用自定义中间件进行异步
行动
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)))
)
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)
})
下面的代码只是一个帮助程序,用于将react nativenavigator.geolocation.getCurrentPosition
转换为可观察的,而不是接受回调的函数
callBackToObservable.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)))
)
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)
})
是什么导致了错误
正在尝试通过商店:
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)))
}
)
用于
Geocoder.geocodePosition
问题在于您对mapTo
的使用。你基本上是说“将这个动作映射到一个可观察的对象”,所以现在你的epic返回一个动作的可观察对象Observable
,而不仅仅是一个动作的可观察对象
换句话说,你的史诗现在发出的是可观察的,而不是动作。相反,您需要使用诸如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)))
)
还有一件事——您不需要使用
flatMap
akamergeMap
将getCurrentPosition$
映射到getcurrentpositioncompleted
操作,因为它是1:1。只有当它是1对多的时候,你才会需要它
export const getCurrentPositionEpic = action$ =>
action$.ofType(GET_CURRENT_POSITION)
.mergeMap(() => getCurrentPosition$
.map((response) => getCurrentPositionFulfilled(response))
.catch(error => Observable.of(getCurrentLocationRejected(error)))
)
以您的方式使用它并没有真正的危害,但它可能会使以后维护代码的其他人感到困惑