3

redux-saga はまったく初めてなので、アクションに反応して 3 秒ごとにLANGUAGE_START_CYCLEアクションを繰り返すサガをセットアップしようとしています。LANGUAGE_CYCLE

しかし、私がRedux ストアLANGUAGE_CYCLEにディスパッチしたときに期待したように、サガが実行されることは決してありません。LANGUAGE_START_CYCLE

私が間違っていることは何ですか?私の他のサガは問題なく動いているので、単純なミスだと思います。

// constants/ActionTypes.js
export const LANGUAGE_SET_ACTIVE = "LANGUAGE_SET_ACTIVE";
export const LANGUAGE_START_CYCLE = "LANGUAGE_START_CYCLE";
export const LANGUAGE_STOP_CYCLE = "LANGUAGE_STOP_CYCLE";
export const LANGUAGE_CYCLE = "LANGUAGE_CYCLE";


// actions/language.js
export const cycleLanguage = () => {
    return {
        type: ActionTypes.LANGUAGE_CYCLE
    }
};    

// languageSaga.js
import { actionChannel, call, take, put, race } from 'redux-saga/effects'
import * as ActionTypes from '../constants/ActionTypes';
import * as actions from '../actions/language';

const wait = ms => {
    new Promise(resolve => {
        setTimeout(() => resolve(), ms)
    })
};

export default function * languageSaga() {
    const channel = yield actionChannel(ActionTypes.LANGUAGE_START_CYCLE);
    while (yield take(channel)) {
        while (true) {
            const { stopped } = yield race({
                wait: call(wait, 3000),
                stopped: take(ActionTypes.LANGUAGE_STOP_CYCLE)
            });

            if (!stopped) {
                yield put(actions.cycleLanguage());
            } else {
                break;
            }
        }
    }
}


// sagas.js (root sagas)
export default function * sagas() {
    yield [
        directorySaga(), // Another saga which works fine
        pusherSaga(), // Another saga which works fine
        languageSaga()
    ]
}

動作している私の他のサガの例:

// directorySaga.js
function * fetchDirectory(action) {
    try {
        const directory = yield call(Api.fetchDirectory, action.id);
        yield put(fetchDirectorySucceeded(directory));
    } catch (e) {
        yield put(fetchDirectoryFailed(e.message));
    }
}

export default function * directorySaga() {
    yield * takeLatest(ActionTypes.DIRECTORY_REQUESTED, fetchDirectory);
}
4

2 に答える 2

1

ここで私の質問に答えます。

上記のコードは機能していますが、アクションをトリガーしているときに、Redux Dev Toolsを使用してアクションをストアにディスパッチしていました。

状態を変更したツールを使用して手動でディスパッチLANGUAGE_START_CYCLEしましたが、どうやらこれは saga ミドルウェアに通知されず、私のチャンネルは更新されませんでした:

Redux 開発ツールのディスパッチ

しかし、私のコンポーネントの 1 つで単純なボタンを使用する場合:

<button onClick={() => dispatch(actions.startCycle())}>
    Start
</button>
<button onClick={() => dispatch(actions.stopCycle())}>
    Stop
</button>

佐賀ミドルウェアに通知されました。

アップデート

私のストア構成は次のとおりです。

import { createStore, applyMiddleware, compose } from 'redux'
import createSagaMiddleware from 'redux-saga';
import rootReducer from '../reducers/index';
import sagas from '../sagas/index';

export default function configureStore(initialState) {
  const sagaMiddleware = createSagaMiddleware();
  const store = createStore(rootReducer, initialState, compose(
    applyMiddleware(sagaMiddleware),
    window.devToolsExtension ? window.devToolsExtension() : f => f
  ));

  if (module.hot) {
    // Enable Webpack hot module replacement for reducers
    module.hot.accept('../reducers', () => {
      const nextReducer = require('../reducers');
      store.replaceReducer(nextReducer);
    });
  }

  sagaMiddleware.run(sagas);

  return store;
}
于 2016-06-13T09:24:11.347 に答える