Redux:等待状态更改后再执行其他操作

时间:2018-08-27 17:15:23

标签: node.js reactjs redux

在假设的应用程序中,用户可以创建一本书,并且默认情况下该书有3页。添加书籍和页面后,我想对书籍和页面做其他一些事情。书籍和页面是我的redux存储中的两个单独的化简器,也是数据库中的两个表。我当前的流程是这样:

  1. 用户创建新书。
  2. 调用ADD_BOOK_REQUEST动作
  3. 调用了ADD_PAGES_REQUEST操作
  4. 将图书添加到激发ADD_BOOK_SUCCESS的数据库
  5. 页面已添加到触发ADD_PAGES_SUCCESS的数据库

如上所述,在执行了步骤4和步骤5之后,我想对本书进行其他操作,但是我不确定最好的方法。为了让它暂时运行,目前我有一个setTimeout函数,该函数运行检查新书和带有该bookId的3页。如果商店中有书和3页,请执行其他操作,否则,请再次运行超时。我非常确定这不是实现此目的的最佳方法。 :微笑:

2 个答案:

答案 0 :(得分:0)

Gosha Arinich在他的帖子Detecting state changes with Redux-Saga中描述了一种可能的解决方案。

在那篇文章中,他建议编写一个waitFor函数,该函数将在提供的选择器最终返回true时返回:

function* waitFor(selector) {
  if (yield select(selector)) return; // (1)

  while (true) {
    yield take('*'); // (1a)
    if (yield select(selector)) return; // (1b)
  }
}

它可以这样使用:

function* someSaga() {
  yield call(waitFor, state => getCurrentUser(state) != null);
  // the user is logged in by now
}

另一种可能的解决方案是使用更简单的自定义中间件,该中间件在分派动作后进行检查。

答案 1 :(得分:0)

您有一些选择。

1)在您的React组件中,您可以连接到在ADD_PAGES_SUCCESS时由减速器更新的状态。在componentWillReceiveProps中,您可以检查该连接状态,并在组件中执行步骤(5)之后要执行的操作。

...不是很好,因为componentWillReceiveProps会很快长毛,应尽可能避免。

2)使用redux-thunk或redux-saga:

使用Redux-saga,您可以在ACTION处理程序(sagas)中进行take ACTIONS并执行类似的操作,例如有条件地进行API调用和yield(等待)以等待服务器响应,此时您可能会触发(put次更多操作或进行更多API调用或执行您想要执行的其他任何操作。这不会替换您的reducer,也不会更改您的redux状态。

示例:

// worker Saga: will be fired on ADD_PAGES_SUCCESS actions

function* doStuffAfterAddPages(action) {
  while (true) {
    yield take(ADD_PAGES_SUCCESS);

    try {
      let moreData;
      const result = yield call(api.doSomethingElse);

      if (result.isExpected) {
        moreData = yield call(api.doOtherStuff);
      } else {
        moreData = yield call(api.doOtherStuff);
      }

      yield put(OTHER_STUFF_COMPLETE, { data: moreData });
    } catch (error) {
      yield put(OTHER_STUFF_FAILED, { error: error.message);
    }
  }
}