@chatterbox777

Почему список товаров не сортируется?

Прокидываю диспатч, редьюсер обрабатывает action.type, проверяю через Redux DevTools, сортировка произошла, однако на странице ничего не меняется, пока не перейдешь на другой route и обратно. И пишет, что state is equal (state типа не изменился). Вопрос, как сделать, чтобы стейт отреагировал на сортировку, т.к. по сути значения не меняются, а тупо сортируется порядок расположения объектов в стейте.

shop.jsx (здесь отображается товар)

import React from "react";

import classTags from "./Shop.module.css";
import { Route, BrowserRouter, NavLink } from "react-router-dom";
import InBasket from "./InBasket";

class Shop extends React.Component {
  render() {
    debugger;
    return (
      <BrowserRouter>
        <div className={classTags.dis}>
          <button onClick={() => this.props.sortPrice()}>
            отсортировать по цене
          </button>
          <ul className={classTags.disp}>
            {this.props.items.map((item) => (
              <li key={item.BasketItemId}>
                <div className={classTags.flex_basis}>
                  <img src={item.imgSrc} alt="товар" />
                  <h3>{item.description}</h3>
                  <h2>
                    цена:
                    <span
                      className={`${
                        item.price > 5000 && item.price < 10000
                          ? classTags.mediumPrice
                          : null || item.price < 5000
                          ? classTags.lowPrice
                          : null || item.price > 10000
                          ? classTags.highPrice
                          : null
                      }`}
                    >
                      {item.price}
                    </span>
                  </h2>
                  <button
                    onClick={(e) =>
                      this.props.onButtonBasket(e, item.BasketItemId)
                    }
                  >
                    {item.clicked ? "Товар добавлен" : "Купить"}
                  </button>
                </div>
              </li>
            ))}
          </ul>
        </div>
      </BrowserRouter>
    );
  }
}
export default Shop;

App.js

Cлишком большой код, чтобы вставлять всё.

const mapStateToProps = (state) => {
  return {
    count: state.mainReducer.count,
    history: state.mainReducer.history,
    messages: state.chatReducer.messages,
    users: state.usersReducer.users,
    pageSize: state.usersReducer.pageSize,
    totalUsersCount: state.usersReducer.totalUsersCount,
    currentPage: state.usersReducer.currentPage,
    isFetching: state.usersReducer.isFetching,
    profile: state.profileReducer.profile,
    followed: state.usersReducer.followed,
    login: state.authReducer.login,
    isAuth: state.authReducer.isAuth,
    id: state.authReducer.id,
    photo: state.authReducer.photo,
    basketItems: state.basketReducer.basketItems,
  };
};

const mapDispatchToProps = (dispatch) => {
  return {
    increment: () => dispatch({ type: "INCREMENT", value: 1 }),
    decrement: () => dispatch({ type: "DECREMENT", value: 1 }),
    onDeleteItem: (id) => dispatch({ type: "DELETE_ITEM", key: id }),
    addMessage: (value) => dispatch({ type: "ADD_MESSAGE", value: value }),
    deleteMessage: (id) => dispatch({ type: "DELETE_MESSAGE", key: id }),
    deleteHistory: () => dispatch({ type: "DELETE_HISTORY" }),
    addUser: (person) => dispatch({ type: "ADD_USER", person: person }),
    addCurrentPage: (pageNum) =>
      dispatch({ type: "ADD_CURRENT_PAGE", page: pageNum }),
    getTotalUsersCount: (totalCount) =>
      dispatch({ type: "GET_TOTAL_USERS_COUNT", totalCount: totalCount }),
    isFetched: () => dispatch({ type: "FETCHING" }),
    setUserProfile: (profile) =>
      dispatch({ type: "SET_PROFILE", profile: profile }),
    follow: (result) => dispatch({ type: "FOLLOWING", result: result }),
    auth: (data, auth) =>
      dispatch({ type: "AUTHORIZE", data: data, auth: auth }),
    loginPhoto: (photo) => dispatch({ type: "LOGIN_PHOTO", photo: photo }),
    addItemToBasket: (e, id) =>
      dispatch({ type: "ADD_BASKET", e: e.persist(), id: id }),
    sortPrice: () => dispatch({ type: "SORT_PRICE" }),
  };
};

редьюсер
let initialState = {
  basketItems: [
    {
      BasketItemId: 1,
      description: "Это прекрасный товар, который Вам обязательно стоит взять",
      imgSrc:
        "https://remontdoma24.ru/image/cache/data/ruchnoj-instrument-hoztovary/sadoviy-unstrument-i-inventar/vedra/65428-230x230.jpg",
      price: 5400,
      clicked: false,
    },
    {
      BasketItemId: 2,
      description: "Это прекрасный товар, который Вам обязательно стоит взять",
      imgSrc:
        "https://hailo.moscow/thumb/2/jXDp6iWcmPKzSiOvkaV2IQ/200r200/d/hailo_profiline_solid_0514-079_v_magazine_hailomoscow.jpg",
      price: 4200,
      clicked: false,
    },
    {
      BasketItemId: 3,
      description: "Это прекрасный товар, который Вам обязательно стоит взять",
      imgSrc:
        "https://suplbiz-a.akamaihd.net/media/cache/8d/bc/8dbc89845bdf0a9fb6174979ce950591.jpg",
      price: 1500,
      clicked: false,
    },
    {
      BasketItemId: 4,
      description: "Это прекрасный товар, который Вам обязательно стоит взять",
      imgSrc:
        "https://res.cloudinary.com/lmru/image/upload/f_auto,q_auto,w_278,h_278,c_pad,b_white,d_photoiscoming.png/LMCode/82402777.jpg",
      price: 2400,
      clicked: false,
    },
    {
      BasketItemId: 5,
      description: "Это прекрасный товар, который Вам обязательно стоит взять",
      imgSrc:
        "https://prorab01.ru/upload/w_512/448302da09724b314b3612ba5b8297d1.jpg",
      price: 10890,
      clicked: false,
    },
    {
      BasketItemId: 6,
      description: "Это прекрасный товар, который Вам обязательно стоит взять",
      imgSrc:
        "https://www.alternat.ru/upload/iblock/945/9459eba2a7bf682d267c7aff170f9e75.jpg",
      price: 15400,
      clicked: false,
    },
  ],
};

export const basketReducer = (state = initialState, action) => {
  debugger;
  switch (action.type) {
    case "ADD_BASKET":
      return {
        ...state,
        basketItems: state.basketItems.map((item) =>
          item.BasketItemId === action.id
            ? { ...item, clicked: !item.clicked }
            : item
        ),
      };
    case "SORT_PRICE":
      return {
        ...state,
        basketItems: state.basketItems.sort((a, b) => a.price - b.price),
      };

    default:
      return state;
  }
};
  • Вопрос задан
  • 120 просмотров
Решения вопроса 1
0xD34F
@0xD34F
пишет что state is equal

basketItems: state.basketItems.sort((a, b) => a.price - b.price),

Ну как бы да - что было, то и осталось. Метод sort не создаёт новый массив. Копируйте массив, и сортируйте копию.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

Похожие вопросы