@iamdeveloper
jQuery engeneer

Как сбросить сортировку в redux? Или как вернуть прежнее состояние массива если он уже отсортирован в Redux?

Есть три состояния сортировки товаров: по убыванию цены, по возрастанию цены и по умолчанию (сортировка сбрасывается)
Так вот, у меня изначально страница с товарами загружается без сортировки и срабатывает action 'FETCH_GOODS_SUCCESS'
С помощью селекта я выбираю тип сортировки (срабатывает action 'SORT_GOODS'). Сортировка по убыванию и возрастанию срабатывает четко. Но когда после этой сортировки выбираем "Сортировка по умолчанию" (т.е. сбрасываем сортировку), товары уже не могут вернутся в исходное состояние т.к. массив товаров `goods` уже был отсортирован.

Вот в этом и проблема. Как вернуть прежнее состояние массива goods, каким он был до сортировки? Может как то можно сохранить исходное состояние?

const initialState = {
  goods: [],
  loading: true,
  sortOrder: 'default',
};

const reducer = (state = initialState, action) => {
  switch(action.type) {

   case 'FETCH_GOODS_SUCCESS':
          // подгрузка товаров без сортировки
          return {
              ...state,
              goods: action.payload,
              loading: false
          };

   case 'SORT_GOODS':
      // выполняем сортировку в зависимости от того что выбрали в селекте 
     //  action.payload.type  может быть равным 'increase' || 'decrease' || 'default'   (default - обнуляем сортировку)
      switch(action.payload.type) {
        case 'increase':
          const goodsListInc = state.goods.sort((prev, next) => prev.price - next.price);
          return {
            ...state,
            goods: goodsListInc,
            sortOrder: 'increase'
          };
        case 'decrease':
          const goodsListDec = state.goods.sort((prev, next) => next.price - prev.price);
          return {
            ...state,
            goods: goodsListDec,
            sortOrder: 'decrease'
          };
        default: // обнуляем сортировку
          return  {
            ...state,
            goods: // Не знаю что написать тут. Ведь в этот момент массив goods уже отстортирован,
            sortOrder: 'default'
          };
      }
  }
}
  • Вопрос задан
  • 63 просмотра
Пригласить эксперта
Ответы на вопрос 1
locky_yotun
@locky_yotun
Я видел некоторый джаваскрипт
Товары должны иметь айдишники, и храниться в нормализованном виде, то есть:
const yourStateSnapshot = {
    goods: {
        1: {
            id: '1',
            name: 'Apples',
        },
        2: {
            id: '2',
            name: 'Oranges',
        },
        3: {
            id: '3',
            name: 'Carrot',
        },
    },
};

А для хранения порядка вывода вы можете использовать отдельный кусок стора, содержащий только айдишники, то есть все в итоге будет выглядеть так:
const yourStateSnapshot = {
    order: {
        goods: [2, 3, 1], // исходный порядок
    },
    goods: {
        1: {
            id: '1',
            name: 'Apples',
        },
        2: {
            id: '2',
            name: 'Oranges',
        },
        3: {
            id: '3',
            name: 'Carrot',
        },
    },
};

const getSortedGoods = (state, order) => {
    if (order === 'asc') {
        return state.goods.sort((_a, _b) => {
            const a = _a.name;
            const b = _b.name;
            return a > b ? 1 : (a < b ? -1 : 0);
        });
    }

    if (order === 'desc') {
        return state.goods.sort((_a, _b) => {
            const a = _a.name;
            const b = _b.name;
            return a > b ? -1 : (a < b ? 1 : 0);
        });
    }
    
    return state.order.goods.map(id => state.goods[id]);
};


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

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы