web-dev-qa-db-ja.com

Reduxの非同期アクション

Reactアプリ、Reduxでオンラインサービス(非同期)に(学習するために)ajax呼び出しを行う必要があります。

これは私の店です:

import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import duedates from './reducers/duedates'


export default applyMiddleware(thunk)(createStore)(duedates);

これがアクションです:

import rest from '../Utils/rest';

export function getDueDatesOptimistic(dueDates){
    console.log("FINISH FETCH");
    console.log(dueDates);
    return {
        type: 'getDueDate',
        dueDates
    }
}

export function waiting() {
    console.log("IN WAIT");
    return {
        type: 'waiting'
    }
}


function fetchDueDates() {
    console.log("IN FETCH");
    return rest({method: 'GET', path: '/api/dueDates'});
}

export function getDueDates(dispatch) {
    console.log("IN ACTION");
    return fetchDueDates().done(
        dueDates => dispatch(getDueDatesOptimistic(dueDates.entity._embedded.dueDates))
    )
}

そして、これがレデューサーです。

export default (state = {}, action) => {
  switch(action.type) {
    case 'getDueDate':
        console.log("IN REDUCER")

        return state.dueDates = action.dueDates;
    default:
        return state
  }
}

私が間違っていることを理解できません。アクションはコンポーネントから完全に呼び出されています。しかし、私はこのエラーを受け取ります:

エラー:アクションはプレーンオブジェクトである必要があります。非同期アクションにカスタムミドルウェアを使用します。

私は間違った反応サンクミドルウェアを使用していると思います。何が間違っていますか?

[〜#〜] edit [〜#〜]

現在、アクションはリデューサーを呼び出していますが、リデューサーは状態を変更した後、renderメソッドを再実行していません

    case 'getDueDate':
        console.log("IN REDUCER")

        return state.dueDates = action.dueDates;
32
Pablo

compose関数を使用する必要があると思うので、

import {
  createStore,
  applyMiddleware,
  compose
} from 'redux';
import thunk from 'redux-thunk';
import duedates from './reducers/duedates'

export default compose(applyMiddleware(thunk))(createStore)(duedates);

サンクを使用すると、アクション作成者はプレーンオブジェクトではなく関数を返すことができるため、次のように使用します。

export function getDueDates() {
  return dispatch => {
    console.log("IN ACTION");
    fetchDueDates().done(
      dueDates => dispatch(getDueDatesOptimistic(dueDates.entity._embedded.dueDates))
    )
  };
}

Promiseオブジェクトを返していましたが、それは問題の一部でした。別の部分は、redux-thunkが適切に適用されていないことです。 composeは問題を解決するはずです。

29

受け入れられた答えは、時代遅れ、間違っている、または複雑すぎています。作成のテーマに関するドキュメントは次のとおりです。

http://redux.js.org/docs/api/compose.html

そのため、代わりに次のようにすることができます。

import {createStore, combineReducers, compose, applyMiddleware} from 'redux';
import thunk from 'redux-thunk';

const reducer = combineReducers({
    user: userReducer,
    items: itemsReducer
});


// here is our redux-store
const store = createStore(reducer,
    compose(applyMiddleware(thunk))
);
17
Alexander Mills

compose関数を使用しなくても、実用的なソリューションを実現できると考えています。 redux-thunk のGitHubリポジトリのドキュメントに基づく

redux-thunk: ^2.0.0

import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import duedates from './reducers/duedates'

export function configureStore(initialState = {}) {
  return createStore(
    duedates,
    initialState,
    applyMiddleware(thunk)
  );
}
1
Kevin Farrugia