我正在使用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个。如您所见,这开始变得非常重复,而不是“ DRY”。我想知道是否有一种更清洁的方法可以做到这一点?
答案 0 :(得分:1)
基于先前的回答,我决定为此制定一个切实可行的解决方案。我还添加了使用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"/>
答案 1 :(得分:1)
@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>
)
}