DRY—显示具有子类别的数组中的项目的方法



我正在使用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>

除了我有12个类别,而不是3个类别。正如你所看到的,这开始变得极其重复,而不是"枯燥"。我想知道是否有一种更清洁的方式来做这件事?

基于之前的回答,我决定制定一个真正可行的解决方案。我还使用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"/>

@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>
)
}

最新更新