Мутирование избыточных состояний между отправками - PullRequest
0 голосов
/ 07 мая 2018

Я использую React и Redux и пытаюсь отправить действие от компонента, но получаю следующую ошибку:

AJAX CALL Инвариантное нарушение: между диспетчерами в пути обнаружена мутация состоянияdashboard.categories.0.onClick.Это может вызвать неправильное поведение.(http://redux.js.org/docs/Troubleshooting.html#never-mutate-reducer-arguments)

Можно предположить следующее:

menu = [
  {title: "video", onClick: false},
  {title: "gif", onClick: false},
  {title: "website", onClick: false}
];

title = 'video';

Здесь используется функция компонента:

itemCheck() {
  const {menu, title, actions} = this.props;
  actions.updateCategoryClick(title, [...menu]);
}

Действие Redux:

export function updateCategoryClickSuccess(categories) {
  return {type: actionTypes.UPDATE_CATEGORY_CLICK_SUCCESS, categories};
}

export function updateCategoryClick(category, categories) {
  return function(dispatch) {
    dispatch(beginAjaxCall());
    return Utils.updateMenuClick(category, categories)
      .then(categories => {dispatch(updateCategoryClickSuccess(categories));})
      .catch(error => {dispatch(ajaxCallError(error));});
  };
}

И используемая функция полезности:

export function updateMenuClick(item, menu) {
  return new Promise((resolve) => {
    const index = menu.findIndex((object => object.title === item));
    menu[index].onClick = !menu[index].onClick;
    resolve(menu);
  });
}

Вопрос: Почему мне говорят, что между диспетчеризацией происходит изменение состояния, если фактически то, что я отправляю, не является исходным состоянием (в данном случае menu), а вместо этого отправляет ему новую копию состояния (в этомcase [...menu])?И как мне это исправить?Спасибо всем!

1 Ответ

0 голосов
/ 07 мая 2018

[...menu] создает поверхностную копию, поэтому this.props.menu[index] и [...menu][index] все еще ссылаются на один и тот же объект.

Попробуйте заменить menu[index].onClick = !menu[index].onClick на:

menu[index] = { ...menu[index], onClick: !menu[index].onClick }

Возможно,лучше сделать эту логику в редукторе.

Кроме того, возвращать обещание в вашем updateMenuClick немного бессмысленно, поскольку он не асинхронный.

...