Действие Redux не восстановлено из-за изменения состояния - PullRequest
0 голосов
/ 10 мая 2018

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

click = true

categories = [
  {title: "all", onClick: false},
  {title: "video", onClick: false},
  {title: "gif", onClick: false},
  {title: "website", onClick: false}
]

finalCategories = [
  {title: "all", onClick: true},
  {title: "video", onClick: true},
  {title: "gif", onClick: true},
  {title: "website", onClick: true}
]

У меня здесь есть набор редукционных действий:

import * as actionTypes from './actionTypes';
import {beginAjaxCall, ajaxCallError} from './ajaxStatusActions';
import * as Utils from './utils/dashboardActionsUtils';

export function updateCategoriesSuccess(categories) {
  return {type: actionTypes.UPDATE_CATEGORIES_SUCCESS, categories};
}

export function categoryAllClick(categories, click) {
  return function(dispatch) {
    dispatch(beginAjaxCall());
    const finalCategories = Utils.updateMenuOnAll(categories, click);
    dispatch(updateCategoriesSuccess(finalCategories));
  };
}

Где:

export function updateMenuOnAll(menu, click) {
  const finalMenu = Object.assign([], menu);
  if (click) {
    finalMenu.map(item => item.onClick = true);
  } else {
    finalMenu.map(item => item.onClick = false);
  }
  return finalMenu;
}

Однако,когда я звоню categoryAllClick(categories, click), actionTypes.UPDATE_CATEGORIES_SUCCESS не попадает в мой редуктор:

import * as actionTypes from '../actions/actionTypes';
import initialState from './initialState';

export default function dashboardReducer(state = initialState.dashboard, action) {
  switch(action.type) {
    case actionTypes.UPDATE_CATEGORIES_SUCCESS:
      return Object.assign({}, state, {categories: action.categories});

    default:
      return state;
  }
}

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

2 Uncaught Error: A state mutation was detected between dispatches, in the path `dashboard.categories.0.onClick`. This may cause incorrect behavior. (http://redux.js.org/docs/Troubleshooting.html#never-mutate-reducer-arguments)

Что-то я делаю неправильно в экспортированной функции updateMenuOnAll, чтобы вызвать эту мутацию состояния?Я думал, что использование Object.assign() позволит избежать этой проблемы.Спасибо!

РЕДАКТИРОВАТЬ

Следующим компонентом реакции является тот, который вызывает categoryAllClick, при нажатии на соответствующий div:

import React from 'react';
import PropTypes from 'prop-types';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import * as dashboardActions from '../../../../../actions/dashboardActions';

class CheckboxItem extends React.Component {
  constructor() {
    super();
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    const {menu, title, type, categoryAllClick, tagAllClick, actions} = this.props;
    if (type === "categories") {
      if (title === "all") {
        actions.categoryAllClick(menu, !categoryAllClick);
      } else {
        actions.updateCategories(title, menu);
      }
    } else if (type === "tags") {
      if (title === "all") {
        actions.tagAllClick(menu, !tagAllClick);
      } else {
        actions.updateTags(title, menu);
      }
    }
  }

  render() {
    return (
      <div className="div-common-menu-item" onClick={this.handleClick}>
        // Child componenets here
      </div>
    );
  }
}

CheckboxItem.propTypes = {
  menu: PropTypes.array.isRequired,
  title: PropTypes.string.isRequired,
  type: PropTypes.string.isRequired,
  categories: PropTypes.array.isRequired,
  tags: PropTypes.array.isRequired,
  categoryAllClick: PropTypes.bool.isRequired,
  tagAllClick: PropTypes.bool.isRequired,
  actions: PropTypes.object.isRequired
};

function mapStateToProps(state) {
  return {
    categories: state.dashboard.categories,
    tags: state.dashboard.tags,
    categoryAllClick: state.dashboard.categoryAllClick,
    tagAllClick: state.dashboard.tagAllClick
  };
}

function mapDispatchToProps(dispatch) {
  return {
    actions: bindActionCreators(dashboardActions, dispatch)
  };
}

const connectedStateAndProps = connect(mapStateToProps, mapDispatchToProps);
export default connectedStateAndProps(CheckboxItem);

Ответы [ 4 ]

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

Проблема была в функции updateMenuOnAll.Переписав его ниже, исправил проблему.Спасибо всем!

export function updateMenuOnAll(menu, click) {
  return menu.map(item => ({title: item.title, onClick: click}));
}
0 голосов
/ 11 мая 2018

Это потому, что вы не должны вызывать categoryAllClick(categories, click) напрямую, а вместо этого использовать диспетчер. Например, если вы реагируете, используя react-redux, вы «подключаете» свой компонент (используя import { connect } from 'react-redux';), передавая свою функцию в аргументе mapDispatchToProps.

Сказав это, вы правы, если предположите, что использование Object.assign не изменяет ваше состояние.

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

Ваша updateMenuOnAll функция неверна, тремя способами:

  • Она мутирует элементы, когда вы зацикливаете их
  • map() возвращает новый массив, но вы 'игнорирование этого возвращаемого значения
  • Использование Object.assign() - неправильный способ копирования массива.

Лучшим подходом будет:

export function updateMenuOnAll(menu, click) {
  const newOnClick = !!click;

  const finalMenu = menu.map(item => ({...item, onClick : newOnClick}));
  return finalMenu;
}
0 голосов
/ 11 мая 2018

Я не вижу код, который у вас есть в функции "Utils.updateMenuOnAll", но если он изменяет категории вашего объекта, вы можете увидеть эту ошибку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...