Сортировка данных в действиях редуктора - PullRequest
1 голос
/ 04 марта 2020

Я пытаюсь создать кнопку сортировки, которая при нажатии будет сортировать карточки меню по алфавиту. У меня вопрос как мне иметь функцию сортировки, закодированную в Reducer and Actions ? Я добавил псевдокод для сортировки в Редукторе. Когда я нажимаю кнопку, я получаю "(TypeError): state.slice не является функцией".

Редактировать: Добавлен компонент моей кнопки и главный контейнер.

Действия:

export const sortMenus = () => {
  return dispatch => {
    dispatch({ type: "LOADING_MENUS" });
    fetch(`/api/menus`)
      .then(res => res.json())
      .then(responseJSON => {
        dispatch({ type: "SORT_MENUS", cards: responseJSON });
      });
  };
};

Редуктор:

export default function MenusReducer(
  state = {
    cards: [],
    loading: false
  },
  action
) {
  switch (action.type) {
    case "LOADING_MENUS":
      return {
        ...state
      };
    case "ADD_MENUS":
      return {
        ...state,
        cards: action.cards
      };
    case "SORT_MENUS":
      return state.slice().sort(function(menu1, menu2) {
        if (menu1.name < menu2.name) return -1;
        if (menu1.name < menu2.name) return 1;
        return 0;
      });
    default:
      return state;
  }
}

Компонент кнопки:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { sortMenus } from ".././actions/dataActions";

import Row from "react-bootstrap/Row";
import Container from "react-bootstrap/Container";

class SortButton extends Component {
  constructor() {
      super(); 
      this.state = { menus: [] };
    }

    handleMenuSort = e => {
        this.props.sortMenus()
    };

    render() {
      return (
        <Container>
            <Row>
              <div>
                  <button id="sort-button" title="Sort Menus" onClick= {this.handleMenuSort}>Sort Menus</button>
              </div>
            </Row>
        </Container>
        )
      }


    }

    const mapStateToProps = state => {
        return {
          menus: state.menus
        }
    };

    const mapDispatchToProps = dispatch => {
        return {
            sortMenus: params => dispatch(sortMenus(params)),
        }
    };


export default connect(mapStateToProps, mapDispatchToProps)(SortButton)

Контейнер:

class MainContainer extends Component {

  displayCards = () => {
      switch(this.props.path) {
          case "menus":
              return (this.props.menus.cards.map(card => (
                  <NavLink style={{ color: "black" }} to={`/menus/${card.id}`} key={card.id}><MenuCard view={this.props.displayObject} info={card} /></NavLink>
              )));

          default:
              return (<div>Empty</div>)
      }
  };

  render() {
      return (
          <CardColumns>
              {this.displayCards()}
          </CardColumns>
        )
     }
  }

  const mapStateToProps = state => {
      return {
          menus: state.menus
      }
  };

  const mapDispatchToProps = dispatch => {
      return {
          displayObject: (id, category, type) => dispatch(displayObject(id, category, type)),
      }
  };

  export default connect(mapStateToProps, mapDispatchToProps)(MainContainer)

Ответы [ 3 ]

1 голос
/ 04 марта 2020

Ваш state является объектом, а не массивом. Вы, скорее всего, хотите отсортировать сохраненный массив cards.

state.cards.slice(... вместо state.slice(...

case "SORT_MENUS":
  return state.cards.slice().sort(function(menu1, menu2) {
    if (menu1.name < menu2.name) return -1;
    if (menu1.name < menu2.name) return 1;
    return 0;
  });

Примечание: Вы также можете очистить / установить loading состояние при успешной загрузке данных. ;)

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

Вы отображаете неопределенное состояние в mapStateToProps, затем отображаете его в компоненте. Измените mapStateToProps, чтобы получить доступ к правильному определенному свойству.

const mapStateToProps = state => ({
  cards: state.cards,
});

Затем вы можете перебрать новый cards prop.

case "menus":
  return (this.props.cards.map(card => (
    <NavLink
      style={{ color: "black" }}
      to={`/menus/${card.id}`}
      key={card.id}
    >
      <MenuCard view={this.props.displayObject} info={card} />
    </NavLink>
  )));
0 голосов
/ 04 марта 2020

в редукторе вы определили состояние как объект и пытаетесь выполнить над ним массив. state.slice(). slice - это функция, доступная для массивов. так что его ошибка. вы должны делать

state.cards.slice().sort((a,b)=> a-b)

0 голосов
/ 04 марта 2020

Вы можете просто сохранить извлеченное меню в состоянии приложения. Вы можете иметь отдельное действие, скажем, SORT_MENU_BY_ALPHABET. Вы можете просто отправить это действие на обработчик кнопки, а также на Ajax success. эта отправка может не иметь никакой полезной нагрузки.

надеюсь, что это поможет.

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