Redux-Saga:异步任务被调用两次

时间:2018-03-28 04:01:10

标签: redux-saga

我是redux-saga的新手并试图在我的React应用程序中替换redux-thunk。出于某种奇怪的原因,我的异步任务(worker)正在被执行两次(但只有当内部存在AJAX请求时才会发生 - 如果存在正常的副作用,例如console.log则不会发生)。

从下面可以看到,我在componentDidMount中只调用了一次getChildData。但是,我的getChildDataAsync生成器函数执行两次(除非我注释掉getChildData(这是一个异步请求返回一个promise)。请求有效,我看到了我的响应数据,但随后又发出了另一个请求。

起初我认为这可能与位置更改有关,但这种情况发生在首次访问网站/硬刷新时​​。

以下是我设置传奇的方法:

saga.js

import axios from 'axios';
import { call, put, take, cancel, takeLatest } from 'redux-saga/effects';
import { push, LOCATION_CHANGE } from 'react-router-redux';
import {
  CHILD_DATA_LOADING,
  CHILD_DATA_SUCCESS,
  CHILD_DATA_ERROR,
} from 'src/redux/actions/actionTypes';
import { getChildData } from 'src/api/search';

// Worker Saga - API Request
export function* getChildDataAsync(action) {
  const { id } = action;
  const params = { id, storageKeys, dataCategory, from };

  try {
    const response = yield call(getChildData, params);
    yield put({
      type: CHILD_DATA_SUCCESS,
      childData: response.data,
    });
  } catch (error) {
    yield put({
      type: CHILD_DATA_ERROR,
      childDataError: true,
      error,
    });
  }
}

// Watcher Saga
export function* watchGetChildData() {
  const childWatcher = yield takeLatest(CHILD_DATA_SUCCESS, getChildDataAsync);
}

// Root Saga - Generator Function
export default function* rootSaga() {
  yield [
    // Combine all watcher sagas
    watchGetChildData(),
  ];
}

store.js

// @flow
import { createStore, applyMiddleware } from 'redux';
import { routerMiddleware } from 'react-router-redux';
import createHistory from 'history/createHashHistory';
import rootReducer from 'src/redux/reducers/index';
import { createLogger } from 'redux-logger';
import createSagaMiddleware from 'redux-saga';
import rootSaga from 'src/redux/sagas/sagas';
import thunk from 'redux-thunk';

// React Router Redux
export const history = createHistory();

// Redux Saga
const sagasMiddleware = createSagaMiddleware();

// Add Redux Logging Only to DEV/TST Environments
const middleware = applyMiddleware(thunk, sagasMiddleware, routerMiddleware(history));

// Create store
const store = createStore(rootReducer, middleware);

// Run Redux-Saga Watchers
sagasMiddleware.run(rootSaga);

export default store;

childDataCreator.js

// @flow
import {
  CHILD_DATA_SUCCESS,
  CHILD_DATA_ERROR,
} from 'src/redux/actions/actionTypes';


// Description: Async Request to Get Child Data for Vendors/Sets
export function getChildData(
  id: string,
) {
  return { type: CHILD_DATA_SUCCESS, id };
}

反应组件

class DataView extends Component<Props> {
  componentDidMount() {
      const _id = '12345';
      this.props.getChildData(_id);
    }
  }

  rest of class....

1 个答案:

答案 0 :(得分:0)

我认为最初的<form method="post"> //my code <input type="submit" value=" OK " /> <button type="submit" formaction="/clear">Clear data</button> <p> Status :<%= status%></p> </form> 调用应该触发类似getChildData动作的内容,这是传奇应该关注的内容。

CHILD_DATA_REQUEST

一旦触发,// Description: Async Request to Get Child Data for Vendors/Sets export function getChildData( id: string, ) { return { type: CHILD_DATA_REQUEST, id }; } // In your saga watcher function const childWatcher = yield takeLatest(CHILD_DATA_REQUEST, getChildDataAsync); 将被调用,getChildDataAsync将在请求成功时触发,我猜这是预期的行为(考虑到命名的常见操作,这是有道理的。)