有条件地在史诗中获取数据

时间:2017-11-06 21:51:44

标签: redux rxjs5 redux-observable

说我有以下史诗:

const getPostsEpic = (action$, store) => {
    return action$.ofType(actionTypes.REQUEST_POSTS)
        .switchMap(action =>
            ajax.getJSON(`api/posts?key=${action.key}`)
            .map(response =>
                receivePosts({type: RECEIVE_POSTS, posts: response})
            ).takeUntil(
                action$.ofType(actionTypes.ABORT_GET_POSTS)
            )
};

并说我的减速机就像

function reducer(
  state = {
    isFetching: false,
    didInvalidate: true,
    items: []
  },
  action
) {
  switch (action.type) {
    case INVALIDATE_POSTS:
      return Object.assign({}, state, {
        didInvalidate: true
      })
    case REQUEST_POSTS:
      return Object.assign({}, state, {
        isFetching: true,
        didInvalidate: false
      })
    case RECEIVE_POSTS:
      return Object.assign({}, state, {
        isFetching: false,
        didInvalidate: false,
        items: action.posts,
      })
    default:
      return state
  }
}

我想确保只有在状态为didInvalidate === true的情况下才会提取帖子,是否有一种方法可以让我的史诗成功?可以做这样的事情,但它不是那么漂亮的IMO:

const getPostsEpic = (action$, store) => {
    return action$.ofType(actionTypes.REQUEST_POSTS)
        .switchMap(action => {
            const state = store.getState();
            if (state.didInvalidate) {
                return ajax.getJSON(`api/posts?key=${action.key}`)
                    .map(response =>
                        receivePosts({type: RECEIVE_POSTS, posts: response})
                    ).takeUntil(
                        action$.ofType(actionTypes.ABORT_GET_POSTS)
                )
            else {
                return Observable.of({type: RECEIVE_POSTS, posts: state.items});
            }
        }
};
是的,我和React一起使用它。我确定这是一个非常常见的问题,所以也许在我的史诗之外有更好的处理方法吗?

1 个答案:

答案 0 :(得分:0)

您可以使用if进行分支,如下所示:

const mockAjax = () => Promise.resolve({posts: [4, 5, 6, 7]});

const fetchPost = (action$) => Rx.Observable.fromPromise(mockAjax())
  .map(({posts}) => ({type: RECEIVE_POSTS, posts}))
  .takeUntil(action$.ofType(ABORT_GET_POSTS))

const defaultPosts = (action$, store) => Rx.Observable.of({type: RECEIVE_POSTS, posts: store.getState().items});

const getPostsEpic = (action$, store) =>
  action$.ofType(USER_REQUEST)
    .mergeMap(() => Rx.Observable.if(
      () => store.getState().didInvalidate, // condition
      fetchPost(action$), // if true
      defaultPosts(action$, store) // if false
    )
    .do(x => console.log(x))
)

检查她的演示:http://jsbin.com/jodaqopozo/edit?js,console,output

点击有效/无效按钮,然后点击“发布请求”'将记录不同的值。

希望这有帮助。