zoukankan      html  css  js  c++  java
  • [React] Create a queue of Ajax requests with redux-observable and group the results.

    With redux-observable, we have the power of RxJS at our disposal - this means tasks that would otherwise be complicated and imperative, become simple and declarative. In this lesson we’ll respond to an action by queuing up 2 separate Ajax requests that will execute sequentially. Then we’ll group the results from both into an array and produce a single action from our epic that will save the data into the redux store

    // action
    
    export const FETCH_STORIES = 'FETCH_STORIES';
    export const FETCH_STORIES_FULFILLED = 'FETCH_STORIES_FULFILLED';
    
    export function fetchStoriesAction(count = 5) {
      return {
        type: FETCH_STORIES,
        payload: count
      }
    }
    
    export function fetchStoriesFulfilledAction(stories) {
      return {
        type: FETCH_STORIES_FULFILLED,
        payload: stories
      }
    }
    // epics
    
    import {Observable} from 'rxjs';
    import {combineEpics} from 'redux-observable';
    import {FETCH_STORIES, fetchStoriesFulfilledAction} from "../actions/index";
    
    const topStories = `https://hacker-news.firebaseio.com/v0/topstories.json?print=pretty`;
    const url = (id) => `https://hacker-news.firebaseio.com/v0/item/${id}.json?print=pretty`;
    
    function fetchStoriesEpic(action$) {
      return action$.ofType(FETCH_STORIES)
        .switchMap(({payload}) => {
          return Observable.ajax.getJSON(topStories)
            // slice first 5 ids
            .map(ids => ids.slice(0, 5))
            // convert ids -> urls
            .map(ids => ids.map(url))
            // convert urls -> ajax
            .map(urls => urls.map(url => Observable.ajax.getJSON(url)))
            // execute 5 ajax requests
            .mergeMap(reqs => Observable.forkJoin(reqs))
            // results -> store
            .map(stories => fetchStoriesFulfilledAction(stories))
        })
    }
    
    export const rootEpic = combineEpics(fetchStoriesEpic);
    import {FETCH_STORIES, FETCH_STORIES_FULFILLED} from "../actions/index";
    
    const initialState = {
      stories: [],
      loading: false,
    };
    
    export function storiesReducer(state = initialState, action) {
      switch(action.type) {
        case FETCH_STORIES:
          return {
            stories: [],
            loading: true
          };
        case FETCH_STORIES_FULFILLED:
          return {
            stories: action.payload,
            loading: false
          };
        default: return state;
      }
    }
    
    export default storiesReducer;
    // component
    
    import React from 'react';
    import {connect} from "react-redux";
    import {fetchStoriesAction} from "../actions/index";
    
    export function Stories(props) {
      if (props.loading) {
        return (
          <p>Please wait...</p>
        )
      }
      return (
        <div>
          <button type="button" onClick={props.loadStories}>Load top 5 stories</button>
          <StoryList stories={props.stories} />
        </div>
      )
    }
    
    function StoryList(props) {
      return (
        <ul>
          {props.stories.map(story =>
            <li key={story.id}>
              <a href={story.url}>{story.title}</a>
            </li>
          )}
        </ul>
      );
    }
    
    function mapState(state) {
      return state;
    }
    
    function mapDispatch(dispatch) {
      return {
        loadStories: () => dispatch(fetchStoriesAction())
      }
    }
    
    export default connect(mapState, mapDispatch)(Stories);
  • 相关阅读:
    写给新的一年(2015)
    Lucene.Net 入门级实例 浅显易懂。。。
    EF webapi json序列化 表间相互引用 无限循环问题解决方案
    java枚举使用详解,整理的很好,只能收下。。。
    mac
    ASP.NET Web API 全局权限和异常处理
    c# 与 java 语法异同
    tfs 报错解决方案:tf400324
    使用C#开发ActiveX控件
    android 更新listview 其中一行的数据显示
  • 原文地址:https://www.cnblogs.com/Answer1215/p/7675215.html
Copyright © 2011-2022 走看看