0

バックグラウンド

redux と react ルーターを使用して、ユニバーサルな反応アプリケーションを作成しています。サーバー側のレンダリングと基本的な redux アクション (ストアでブール値を変更する) を使用して、ほとんどのアプリケーションをセットアップしました。ここで、アプリのデータを取得するためにいくつかの API 呼び出しを行いたいと思います。

現在の実装

redux-api-middleware を使用することをお勧めしますが、ストアに追加するデータを取得できません。ドキュメントに従って、このようなアクションを作成しました。

example-action.js

import { CALL_API } from `redux-api-middleware`;


export function fn_get_data () {
  [CALL_API]: {
    endpoint: 'http://www.example.com/api/users',
    method: 'GET',
    types: ['REQUEST', 'SUCCESS', 'FAILURE']
  }
}

このアクションは、ページのボタン クリックで実行されます。アクションが発生するのがわかりますが、ストアには何も入りません。SUCCESSアクション用のカスタム コードを追加してconsole.log()、応答できましたが、ストアにデータを取得できませんでした。

また、ドキュメントに記載されているのと同じ方法でミドルウェアをストアに追加しました。

configureStore.js

import { createStore, applyMiddleware, combineReducers } from 'redux';
import { apiMiddleware } from 'redux-api-middleware';
import reducers from './reducers';

const reducer = combineReducers(reducers);
const createStoreWithMiddleware = applyMiddleware(apiMiddleware)(createStore);

export default function configureStore(initialState) {
  return createStoreWithMiddleware(reducer, initialState);
}

これまでに試した

payloadこれまでのところ、アクションをエクスポート可能なシンボルにしてレデューサーで呼び出し、redux-api-middlewareの属性から得られる現在の状態にデータをマージしようとするなど、アクションでさまざまなことを試しましたが、運がない。

質問

私は本当に2つの質問があります

  • ドキュメントにレデューサーがないのはなぜですか?これは見過ごされているだけですか?それとも、応答からのデータがストアに直接送られるだけですか?
  • 呼び出したデータがストアに追加されないのはなぜですか (何が足りないのですか)?

この問題に関するヘルプ、説明、または建設的な批判は本当に感謝しています。

4

3 に答える 3

2

私が見る限りredux-api-middleware、API 呼び出しを行い、成功/失敗アクションをディスパッチし、場合によっては応答を少し処理するための一連の機能を提供します。ただし、レデューサーでこれらのアクションをどのように処理するかは、あなた次第です。したがって、ミドルウェアに dispatch を要求する場合は、ハンドラーをレデューサー ロジックに"MY_REQUEST_SUCCESS"追加し、状態を適切に更新する必要があります。"MY_REQUEST_SUCCESS"

于 2016-11-03T21:18:25.187 に答える
2

解決

マーカーリクソンが言ったように、ライブラリはツールを提供するだけで、アクションに応答するためにreduceresを書く必要があります。私の場合、最終的に次のレデューサーでデータを取得しました。

example-reducer.js

import * as ExampleActionType from "../action/example-action";
import Immutable from "immutable";

let defaultState = Immutable.fromJS({
  fakeData: {}
});

function exampleState (state = defaultState, action) {
  switch (action.type) {

    case ExampleActionType.REQUEST : {
        console.log(action);
        return state;
    }

    case ExampleActionType.SUCCESS : {
        console.log(action);
        return state.merge({fakeData: action.payload });
    }

    case ExampleActionType.FAILURE : {
        console.log(action);
        return state;
    }

    default:
        return state;
  }
}

このようなシンボルもエクスポートする必要がありました

example-action.js

export const REQUEST = Symbol('REQUEST');
export const SUCCESS = Symbol('SUCCESS');
export const FAILURE = Symbol('FAILURE');

結論

非常に少ないコードで API リクエストを作成するために必要なすべてのツールを提供する素晴らしいライブラリです。私のように悩んでいる方の参考になれば幸いです。

于 2016-11-04T09:14:24.933 に答える
0

redux-api-middlewareストアにデータを保存するためのものではありません (そのため、リデューサーをセットアップする必要はありません)。私は実際にライブラリredux-cached-api-middlewareを構築しました。これは、その上に薄いレイヤーとして機能し、redux-api-middlewareキャッシング (単純な保存として簡単に使用できます) 機能を追加します。

コンポーネントの例を次に示します。

import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import api from 'redux-cached-api-middleware';
import Items from './Items';
import Error from './Error';

class ExampleApp extends React.Component {
  componentDidMount() {
    this.props.fetchData();
  }

  render() {
    const { result } = this.props;
    if (!result) return null;
    if (result.fetching) return <div>Loading...</div>;
    if (result.error) return <Error data={result.errorPayload} />;
    if (result.successPayload) return <Items data={result.successPayload} />;
    return <div>No items</div>;
  }
}

ExampleApp.propTypes = {
  fetchData: PropTypes.func.isRequired,
  result: PropTypes.shape({}),
};

const CACHE_KEY = 'GET/items';

const enhance = connect(
  state => ({
    result: api.selectors.getResult(state, CACHE_KEY),
  }),
  dispatch => ({
    fetchData() {
      return dispatch(
        api.actions.invoke({
          method: 'GET',
          headers: { Accept: 'application/json' },
          endpoint: 'https://my-api.com/items/',
          cache: {
            key: CACHE_KEY,
            strategy: api.cache
              .get(api.constants.CACHE_TYPES.TTL_SUCCESS)
              .buildStrategy({ ttl: 10 * 60 * 1000 }), // 10 minutes
          },
        })
      );
    },
  })
);

export default enhance(ExampleApp);

これはキャッシュされた方法で機能しますが、カスタム関数を簡単に渡すことができshouldFetch、常に API から再フェッチします。

const enhance = connect(
  state => ({
    result: api.selectors.getResult(state, CACHE_KEY),
  }),
  dispatch => ({
    fetchData() {
      return dispatch(
        api.actions.invoke({
          method: 'GET',
          headers: { Accept: 'application/json' },
          endpoint: 'https://my-api.com/items/',
          cache: {
            key: CACHE_KEY,
            shouldFetch: () => true
          },
        })
      );
    },
  })
);

セットアップは次のとおりです (実際に redux 状態への応答の保存を処理する API レデューサーに注意してください)。

import { createStore, combineReducers, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import { apiMiddleware } from 'redux-api-middleware';
import api from 'redux-cached-api-middleware';
import reducers from './reducers';

const store = createStore(
  combineReducers({
    ...reducers,
    [api.constants.NAME]: api.reducer,
  }),
  applyMiddleware(thunk, apiMiddleware)
);
于 2018-08-10T17:12:46.983 に答える