Измените состояние массива флажков на редукторе по мере его изменения в пользовательском интерфейсе. - PullRequest
0 голосов
/ 11 декабря 2018

У меня есть что-то вроде этого в React:

const CheckboxItems = (t) => [ // that t is just a global prop
  {
    checked: true,
    value: 'itemsCancelled',
    id: 'checkBoxItemsCancelled',
    labelText: t('cancellations.checkBoxItemsCancelled'),
  },
  {
    checked: true,
    value: 'requestDate',
    id: 'checkboxRequestDate',
    labelText: t('cancellations.checkboxRequestDate'),
  },
  {
    checked: true,
    value: 'status',
    id: 'checkboxStatus',
    labelText: t('cancellations.checkboxStatus'),
  },
  {
    checked: true,
    value: 'requestedBy',
    id: 'checkboxRequestedBy',
    labelText: t('cancellations.checkboxRequestedBy'),
  },
];

class TableToolbarComp extends React.Component {
  state = {
    items: CheckboxItems(),
  };

  onChange = (value, id, event) => {
    const { columnsFilterHandler } = this.props;
    this.setState(({ items }) => {
      const item = items.slice().find(i => i.id === id);
      if (item) {
        item.checked = !item.checked;
        columnsFilterHandler(id, item.value, item.checked);
        return { items };
      }
    });
  };

  render() {
    const { items } = this.state;

    return(
      <>
             {items.map(item => (
                <ToolbarOption key={item.id}>
                  <Checkbox
                    id={item.id}
                    labelText={item.labelText}
                    value={item.value}
                    checked={item.checked}
                    onChange={this.onChange}
                  />
                </ToolbarOption>
              ))}
      </>
    )
  }

export default compose(
  connect(
    ({ cancellations }) => ({
      columnId: cancellations.columnId,
      columnValue: cancellations.columnValue,
      isChecked: cancellations.isChecked,
    }),
    dispatch => ({
      columnsFilterHandler: (columnId, columnValue, isChecked) => {
        dispatch(columnsFilterAction(columnId, columnValue, isChecked));
      },
    }),
  ),
)(translate()(TableToolbarComp));

Это работает очень хорошо и отправляет данные, которые мне нужно будет использовать позже.

Но у меня беспорядок наRedux часть, которая изменяет состояние всех флажков сразу, а не по отдельности, как должно.Итак, когда я снимаю галочку с одного из флажков, остальные 3 также получают checked: false.Я не вижу этого изменения на checked: false в пользовательском интерфейсе, только я вижу его на консоли Redux в браузере.

Это то, что у меня есть в редукторе

const initialState = {
  checkboxes: [
    {
      checked: true,
      value: 'itemsCancelled',
      id: 'checkBoxItemsCancelled',
    },
    {
      checked: true,
      value: 'requestDate',
      id: 'checkboxRequestDate',
    },
    {
      checked: true,
      value: 'status',
      id: 'checkboxStatus',
    },
    {
      checked: true,
      value: 'requestedBy',
      id: 'checkboxRequestedBy',
    },
  ],
}

[ActionTypes.COLUMNS_FILTER](state, action) {
    return initialState.checkboxes.map(checkbox => {
      if (!checkbox.id === action.payload.id) {
        return checkbox;
      }
      return {
        ...checkbox,
        checked: action.payload.isChecked,
      };
    });
 }

Действие:

const columnsFilterAction = (columnId, columnValue, isChecked) => ({
  type: ActionTypes.COLUMNS_FILTER,
  payload: { columnId, columnValue, isChecked },
});

Итак, все, что мне нужно знать, - это то, что мне нужно сделать, чтобы управлять состоянием этих флажков в Redux, когда он работает в React.Все, что я вижу, это то, что когда я переключаю флажки, все они достигают одного и того же состояния.

Ответы [ 2 ]

0 голосов
/ 11 декабря 2018

В качестве логики условий у вас есть !checkbox.id === action.payload.id.Поскольку все ваши идентификаторы флажков являются «правдивыми», тогда этот! Checkbox.id оценивается как ложный и аналогичен записи if(false === action.payload.id).

Я подозреваю, что вы хотели написать: if(checkbox.id !== action.payload.id).

0 голосов
/ 11 декабря 2018

То, что вы хотите сделать, - это поставить id флажка, который вы хотите включить в действии.Это все, что вам нужно в действии для переключения состояния.Затем в редукторе вы хотите отобразить текущее состояние и просто вернуть флажок для любого, который не соответствует id, переданному в действии.Когда id совпадает, верните новую опцию, распространяя свойства текущего флажка на новый объект и устанавливая свойство checked на противоположное.

Учитывая это действие:

const TOGGLE_CHECKBOX = 'TOGGLE_CHECKBOX'
function toggleCheckbox(id) {
  return {
    type: TOGGLE_CHECKBOX,
    id
  }
}

Действия - Redux - Руководство по действиям и создателям действий, предоставленное автором Redux.

Этот редуктор выполнит эту работу.

function checkboxReducer(state = [], action = {}) {
  switch(action.type) {
    case TOGGLE_CHECKBOX:
      return state.map(checkbox => {
        if (checkbox.id !== action.id) {
          return checkbox;
        }
        return {
          ...checkbox,
          checked: checkbox.isChecked ? false : true,
        }
      })
    default:
      return state;
  }
}

Редукторы- Redux - Руководство по редукторам и способам обработки действий, предоставленных автором Redux.

Вот рабочая Кодовая песочница , демонстрирующая ее работу.Вы можете установить флажки, чтобы увидеть, как они переключаются, как и ожидалось.

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