redux - 有条件地获取史诗中的数据

标签 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)
            )
};

并说我的 reducer 类似于
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 中使用它。我确定这是一个非常普遍的问题,所以也许在我的史诗之外有更好的方法来处理这个问题?

最佳答案

您可以使用 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

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

希望这可以帮助。

关于redux - 有条件地获取史诗中的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47146454/

相关文章:

javascript - 使用 test 和 React-testing-library 测试 React 组件

typescript - [Typescript][RxJS] 为什么返回部分类型的可观察对象时没有类型错误?

angular - 正确使用 rxjs-5-to-6-migrate 。 tsconfig 路径的问题

redux - 为什么要在中间件内部处理 Observables,而不是调度组合 Observables 的输出?

reactjs - 在reducers之间共享状态的最佳方式(redux工具包)

reactjs - Redux-表格 : Unable to Dispatch Action on Submit

javascript - 在 RxJS 中,如何获取导致错误的值?

javascript - 将可观察到的响应合并为一个

javascript - 在 redux 中排序史诗

reactjs - 如何防止 Redux 调度重新渲染子组件