web-dev-qa-db-ja.com

redux-observableでajaxの代わりにフェッチを使用する

redux-observableRx.DOM.ajax の代わりに isomporphic-fetch を使用することは可能ですか?

13
Amio.io

(注:_RX.DOM.ajax_はRxJSv4からのものであり、_redux-observable_では機能しません RxJSv5 。v5で同等のものは _Rx.Observable.ajax_ または_import { ajax } from 'rxjs/observable/ajax';_)です。

確かにfetch()やその他のAJAX APIを使用することは可能ですが、他のものよりも簡単に適応できるものもあります!

fetch() AP​​IはPromiseを返します。これはRxJS v5がに組み込みサポートしているです。オブザーバブルを期待するほとんどのオペレーターは、Promiseをそのまま使用できます(mergeMapswitchMapなど)。しかし、RxオペレーターをPromiseに適用してからEpicの残りの部分に渡すことが必要になることがよくあります。そのため、PromiseをObservable内にラップしたい場合がよくあります。

Observable.from(promise)を使用して、Promiseをオブザーバブルにラップできます。

これは、ユーザーのためにフェッチし、JSON応答を要求してから、promiseをオブザーバブルでラップする例です。

_const api = {
  fetchUser: id => {
    const request = fetch(`https://jsonplaceholder.typicode.com/users/${id}`)
      .then(response => response.json());
    return Observable.from(request);
  }
};
_

次に、それをEpicで使用して、必要な演算子を適用できます。

_const fetchUserEpic = action$ =>
  action$.ofType(FETCH_USER)
    .mergeMap(action =>
      api.fetchUser(action.payload) // This returns our Observable wrapping the Promise
        .map(payload => ({ type: FETCH_USER_FULFILLED, payload }))
    );
_

これがこの実用的な例のJSBinです: https://jsbin.com/fuwaguk/edit?js,output


APIコードを制御できる場合は、プロミスをキャンセルできないため、理想的には_Observable.ajax_(または他のObservableベースのAJAX utils))を使用します。

42
jayphelps

そのコードを機能させるために、@ jayphelpsを少し調整しました。これが誰かの時間を節約するのに役立つことを願っています。

import { FETCH_USER } from './actions'
import { ofType } from 'redux-observable'
import { map, mergeMap } from 'rxjs/operators'
import { from } from 'rxjs'

const fetchUserEpic = action$ => {
    return action$.pipe(
        ofType(FETCH_USER),
        mergeMap((action = { user: 'redux-observable' }) => {
            const getRequest = (user) => {
                const request = fetch(`https://api.github.com/users/${user}`)
                    .then(response => response.json())
                return from(request)
            }

            return getRequest(action.user).pipe(
               map(payload => ({ type: FETCH_USER_FULFILLED, payload }))
            )
        })
    )
}
1
Geeganage