СУХОЙ способ отображения элементов из массива с подкатегориями - PullRequest
0 голосов
/ 29 ноября 2018

Я создаю страницу меню, используя React и Redux.В настоящее время у меня есть все меню из более чем 100 пунктов в массиве объектов, которое включает в себя свойство «категория» для типа еды (закуски, гамбургеры, десерты и т. Д.)из предметов и отображал их все так:

render(){
    let foodList = this.props.foodMenu.map((food) => (
        <Food className="food-menu" key={food.id} food={food} addToCart={this.addToCart}/>
    ))

    return (
        <div >
            <h2>Food Menu</h2>
            {foodList}
        </div>
    )

Однако я хочу иметь возможность разделить меню по категориям, что привело меня к следующему:

    render(){
    let appetizers = this.props.foodMenu.filter(food => food.category === 'appetizers').map((food) => (
        <Food className="food-menu" key={food.id} food={food} addToCart={this.addToCart}/>
    ))

    let soupsalad = this.props.foodMenu.filter(food => food.category === 'soupsalad').map((food) => (
        <Food className="food-menu" key={food.id} food={food} addToCart={this.addToCart}/>
    ))


    let steaks = this.props.foodMenu.filter(food => food.category === 'steaks').map((food) => (
        <Food className="food-menu" key={food.id} food={food} addToCart={this.addToCart}/>
    ))


    return (
        <div>
            <h2>Food Menu</h2>
            <h3>Appetizers</h3>
            <div className='container'>
                    {appetizers}
            </div>
            <h3>Soup or Salad</h3>
            <div className='container'>
                    {soupsalad}
            </div>
            <h3>Steak</h3>
            <div className='container'>
                    {steaks}
            </div>
        </div>

За исключением взамениз 3-х категорий у меня 12. Как видите, это начинает становиться чрезвычайно повторяющимся, а не «СУХИМ».Мне было интересно, есть ли более чистый способ сделать это?

Ответы [ 2 ]

0 голосов
/ 30 ноября 2018

@ Geostack опубликовал отличный ответ.Вот также то, что я нашел работающим для моего приложения.

const sortByCategory = (dataArray) => {
    let sortedByCategory = {}
    dataArray.forEach(item => {
        if (sortedByCategory[item.category]) {
            sortedByCategory[item.category].push(item)
        } else {
            sortedByCategory[item.category] = []
            sortedByCategory[item.category].push(item)
        }
    })
    return sortedByCategory
}

render(){
    let sortedData = sortByCategory(this.props.foodMenu)
    let foodMenu = []

    for(let key in sortedData) {
        foodMenu.push(
            <div >
                <h3>{key.toUpperCase()}</h3>
                <br />
                <div>
                    {
                        sortedData[key].map(food => {
                            return (
                                <div key={food.id}>
                                    <Food  key={food.id} food={food} addToCart={this.addToCart}/>
                                    <hr />
                                </div>
                            )
                        })
                    }
                </div>
            </div>
        )
    }

    return (
        <div>
            {foodMenu}
        </div>
    )
}
0 голосов
/ 30 ноября 2018

Исходя из предыдущего ответа, я решил сделать реальное рабочее решение этого.Я также добавил еще один способ сделать это с помощью метода forEach.Пожалуйста, запустите фрагмент, чтобы увидеть результаты.

Ура!

const Food = props => {
  //Do something that make sense with this :)
  const { food, addToCart, className } = props;
  return (
    <React.Fragment>
      Food: {food.id} <br />
    </React.Fragment>
  );
};

const App = props => {
  const categories = {
    Appetizers: "appetizers",
    Soupsalad: "soupsalad",
    Steaks: "steaks"
  };

  var menus1 = [];
  Object.keys(categories).forEach(categorie => {
    var subMenus = props.foodMenu
      .filter(food => food.category === categories[categorie])
      .map((food,i) => (
        <div key={i}>
          <h3>{categorie}</h3>
          <div className="container">
            <Food
              className="food-menu"
              key={food.id}
              food={food}
              addToCart={""}
            />
          </div>
        </div>
      ));
    menus1 = [...menus1, subMenus];
  });

  const menus2 = Object.entries(categories).map(e => {
    return props.foodMenu
      .filter(food => food.category === e[1])
      .map((food,i) => (
        <div key={i}>
          <h3>{e[0]}</h3>
          <div className="container">
            <Food
              className="food-menu"
              key={food.id}
              food={food}
              addToCart={""}
            />
          </div>
        </div>
      ));
  });

  return (
    <React.Fragment>
      <h2>Food Menu1 with foreach</h2>
      {menus1}

      <h2>Food Menu2 with map of map</h2>
      {menus2}
    </React.Fragment>
  );
};


var foodMenu = [
  { id: "food1", category: "appetizers" },
  { id: "food2", category: "soupsalad" },
  { id: "food3", category: "steaks" }
];
const rootElement = document.getElementById("root");
ReactDOM.render(<App foodMenu={foodMenu} />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"/>
...