首次分派未使用的操作时,Redux Reducer会运行多次

时间:2019-03-06 21:32:06

标签: reactjs redux react-boilerplate

更新:我使用的是React-Boilerplate,除了容器/组件中的内容外,均未修改。第一次调度一个新动作时,reduces运行多次,有时运行两次以上,但随后分派相同动作时,则不会运行。这些动作本身不会在重复的reducer调用上触发,而是会更新状态并重新渲染组件。

例如:如果我分派用于更新reducerCase1的action1,但不分派用于更新reducerCase2的action2,则action1将运行一次,而reducerCase1将运行两次。 action2和reducerCase2将不会运行。如果我随后分派action3来更新reducerCase3,则reducerCase1将被多次调用,但是action1,action2和reducerCase2将不会被调用。

如果我以与action1相同的方式调度action2,则它将与action1和reducerCase1相同,在不触发该动作的情况下多次运行reducer。

如果我再次第二次派遣action3,则reducerCase1将根本不会运行(应该是这种情况)。

在这里,我对GET_CATEGORIES和GET_CATS_COMPLETED操作感兴趣:

enter image description here

这是reducer内的控制台日志:

export default function Categories(state = initialState, action) {
  switch (action.type) {
    case GET_CATEGORIES:
      debugger;
      console.log('getting categories...');
      return state.set('isLoading', true);
    case GET_CATEGORIES_COMPLETED:
      debugger;
      console.log('setting categories...');
      return state
        .set('categories', fromJS(action.cats))
        .set('isLoading', false);

enter image description here

由于我所有的reducer都在发生这种情况,因此我认为它与mapDispatchToProps有关:

const mapStateToProps = createStructuredSelector({
  categories: makeSelectCategories(),
  ownerId: makeSelectProfileId(),
  selectedCategoryId: makeSelectSelectedCategoryId(),
  isLoading: makeSelectIsLoading(),
});

const mapDispatchToProps = {
  getCategories,
  setCategory,
};

const withConnect = connect(
  mapStateToProps,
  mapDispatchToProps
);

const withReducer = injectReducer({ key: 'CategoryContainer', reducer });
const withSaga = injectSaga({ key: 'CategoryContainer', saga });

export default compose(
  withSaga,
  withReducer,
  withConnect
)(CategoryContainer);

这是我的动作:

export function getCategories() {
  console.log('inside getCategories()');
  return {
    type: GET_CATEGORIES,
  };
}

export function getCategoriesCompleted(cats) {
  return {
    type: GET_CATEGORIES_COMPLETED,
    cats,
  };
}

最后是传奇:

export default function* CategoryContainerSaga() {
  yield takeLatest(GET_CATEGORIES, getCategories);
}

function* getCategories() {
  try {
    const plidParam = yield call(getPlParam);
    const profileId = yield call(getProfileId);
    const url = getUrl();
    const { categories2, playlist } = yield call(
      getCatsRequest,
      url,
      profileId,
      plidParam
    );
    yield put(getCategoriesCompleted(categories2));
    if (playlist) yield put(setPlaylist(playlist));
  } catch (error) {
    yield put(getCategoriesCompleted([]));
    yield put(setError(error.message));
  }
}

1 个答案:

答案 0 :(得分:0)

由于lecstor的评论,我能够确定这是Redux devtools的预期行为。