react-native - redux-observable 操作必须是普通对象。使用自定义中间件进行异步操作

标签 react-native redux react-redux rxjs5 redux-observable

当我在下面的代码中注释掉 getCurrentPositionEpic 时,该应用程序可以运行。但是,如果我不加注释,就会出现错误:

Actions must be plain objects. Use custom middleware for async actions.

export const rootEpic = combineEpics(
  fetchCategoriesEpic,
  getCurrentLocationEpic,
  getCurrentPositionEpic
)

const store = createStore(
  rootReducer,
  initialState,
  composeWithDevTools(
    applyMiddleware(createEpicMiddleware(rootEpic))
  )
)

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)))
    )

下面的代码只是一个帮助程序,用于将 React Native 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)
  })

可能导致错误的原因是什么?

尝试路过商店:

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)))
}
)

使用 https://github.com/devfd/react-native-geocoder对于 Geocoder.geocodePosition

最佳答案

问题是您对 mapTo 的使用.你基本上是在说“将这个 Action 映射到一个 Observable”,所以现在你的史诗返回一个 Observable of Observable of actions Observable<Observable<Action>>而不仅仅是 Action 的 Observable。

换句话说,您的史诗现在发射 Observables 而不是发射 Action 。您需要使用像 mergeMap 这样的合并策略运算符, switchMap , 等合并以将内部 Observable 链扁平化/合并到顶级链中。 flatMapmergeMap 的别名, 顺便说一句。

export const getCurrentPositionEpic = action$ =>
  action$.ofType(GET_CURRENT_POSITION)
    .mergeMap(() => getCurrentPosition$
      .flatMap((response) => Observable.of(
        getCurrentPositionFulfilled(response)
      ))
      .catch(error => Observable.of(getCurrentLocationRejected(error)))
    )

还有一件事——你不需要使用 flatMap又名 mergeMap映射 getCurrentPosition$getCurrentPositionFulfilled行动,因为它是 1:1。仅当它是 1 对多时才需要它。

export const getCurrentPositionEpic = action$ =>
  action$.ofType(GET_CURRENT_POSITION)
    .mergeMap(() => getCurrentPosition$
      .map((response) => getCurrentPositionFulfilled(response))
      .catch(error => Observable.of(getCurrentLocationRejected(error)))
    )

按照您的方式使用它并没有什么真正的危害,但它可能会让以后维护代码的其他人感到困惑。

关于react-native - redux-observable 操作必须是普通对象。使用自定义中间件进行异步操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43748204/

相关文章:

reactjs - 如何在不明确提供大量操作上下文的情况下更改深层嵌套状态?

javascript - 为什么我会收到无效值错误?

javascript - FlatList 不会在 Prop 更改时重新渲染

javascript - 未定义“createPolyglotMiddleware”

javascript - 嵌套文本的样式不起作用

react-native - React Native Building版本未反射(reflect)调试所做的更改(Android)

react-native - 如何从 firebase 控制台发送带有自定义数据的测试推送通知?

android - 火力地堡安卓 : App crash when receiving Notification after adding Invites

javascript - React.js 在执行第一个函数后设置回调函数

javascript - “Redux”未定义...以及 ReactRedux 和 ReactDOM