【问题标题】:Saga is not triggered the second time an action is dispatched第二次分派动作时不会触发 Saga
【发布时间】:2020-10-10 09:29:26
【问题描述】:

我正在尝试使用 redux-saga 实现取消任务效果。它在第一次调度时运行良好,但在第二次调度时,它什么也不做。看来传奇已经结束了。这是我的代码:

import { all, put, fork, take, cancel, cancelled } from "redux-saga/effects";

const searchUsers = function* () {
  try {
    yield new Promise((resolve) => setTimeout(resolve, 1500));
    const users = ["Bill Gates"];
    yield put({ type: "SEARCH_USERS_SUCCESS", users });
  } catch (e) {
    // log error
  } finally {
    if (yield cancelled()) {
      console.log("search was cancelled");
    }
  }
};

const searchUsersSaga = function* () {
  const searchAction = yield take("SEARCH_USERS");
  const searchTask = yield fork(searchUsers, searchAction.query);
  const cancleAction = yield take("SEARCH_USERS_CANCEL");

  if (cancleAction.type === "SEARCH_USERS_CANCEL") {
    yield cancel(searchTask);
  }
};

const rootSaga = function* saga() {
  yield all([searchUsersSaga].map(fork));
};

export default rootSaga;

我在这里创建了一个完整的代码:https://codesandbox.io/s/new-fast-snhr0?file=/src/index.js

【问题讨论】:

    标签: reactjs react-redux redux-saga


    【解决方案1】:

    使用take 效果,saga 调用action = getNextAction() 将在分派操作时解析,因此您的searchUsersSaga 应该在while(true) 循环中。

    还有一个问题,如果SEARCH_USERS_SUCCESSsearchUsersSaga 会等待SEARCH_USERS_CANCEL 并且它也会阻塞流,你应该派另一个动作来处理这种情况。

    const searchUsers = function* () {
      try {
        yield new Promise((resolve) => setTimeout(resolve, 1500));
        const users = ["Bill Gates"];
        yield put({ type: "SEARCH_USERS_SUCCESS", users });
      } catch (e) {
        // log error
      } finally {
        yield put({ type: "SEARCH_USERS_END" });
        if (yield cancelled()) {
          console.log("search was cancelled");
        }
      }
    };
    
    const searchUsersSaga = function* () {
      while (true) {
        const searchAction = yield take("SEARCH_USERS");
        const searchTask = yield fork(searchUsers, searchAction.query);
        const cancleAction = yield take([
          "SEARCH_USERS_CANCEL",
          "SEARCH_USERS_END"
        ]);
    
        if (cancleAction.type === "SEARCH_USERS_CANCEL") {
          yield cancel(searchTask);
        }
      }
    };
    
    export const usersReducer = (state = initialState, action) => {
      switch (action.type) {
        ...
        case "SEARCH_USERS_END":
          return {
            ...state,
            isSearching: false
          };
        ...
      }
    };
    
    

    https://codesandbox.io/s/sad-cori-yodq0

    【讨论】:

      猜你喜欢
      • 2013-08-20
      • 1970-01-01
      • 2015-11-26
      • 2019-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-31
      • 1970-01-01
      相关资源
      最近更新 更多