我有一个滚动菜单项,每个项的标题都与id一起硬编码为const
const list = [
{ name: "category1", id: 0 },
{ name: "category2", id: 1 },
{ name: "category3", id: 2 },
{ name: "category4", id: 3 },
{ name: "category5", id: 4 },
{ name: "category6", id: 5 },
{ name: "category7", id: 6 },
{ name: "category8", id: 7 }
];
我有一个json文件,其中包含每个孩子的类别名称:
{
"results": [
{
"category": "category1",
"name": {
"title": "mr",
"first": "ernesto",
"last": "roman"
},
"email": "ernesto.roman@example.com",
"id": {
"name": "DNI",
"value": "73164596-W"
},
"picture": {
"large": "https://randomuser.me/api/portraits/men/73.jpg",
"medium": "https://randomuser.me/api/portraits/med/men/73.jpg",
"thumbnail": "https://randomuser.me/api/portraits/thumb/men/73.jpg"
}
},
{
"category": "category2",
"name": {
"title": "mr",
"first": "adalbert",
"last": "bausch"
},
"email": "adalbert.bausch@example.com",
"id": {
"name": "",
"value": null
} etc....
我想显示这些类别"category": "category1"
,作为菜单的标题,我现在需要启动无状态并从JSON添加它们,从JSON提取部分是在componentDidMount中本地完成的,但是我不确定如何将它们映射为菜单名称以使菜单动态化,我基本上希望得到相同的输出,但是来自json的信息未进行硬编码。这是一个沙盒代码段,不胜感激。
https://codesandbox.io/s/2prw4j729p?fontsize=14&moduleview=1
答案 0 :(得分:1)
看起来您根本不需要对类别列表进行硬编码。在您的componentDidMount()
中,获取json并将结果分组为单独的类别,如下所示:
const json = {
"results": [
{
category: "category1",
name: "Fred"
},
{
category: "category1",
name: "Teddy"
},
{
category: "category2",
name: "Gilbert"
},
{
category: "category3",
name: "Foxy"
},
]
}
const grouped = json.results.reduce((acc, cur) => {
if (!acc.hasOwnProperty(cur.category)) {
acc[cur.category] = []
}
acc[cur.category].push(cur)
return acc;
}, { })
// parent object now has 3 properties, namely category1, category2 and category3
console.log(JSON.stringify(grouped, null, 4))
// each of these properties is an array of bjects of same category
console.log(JSON.stringify(grouped.category1, null, 4))
console.log(JSON.stringify(grouped.category2, null, 4))
console.log(JSON.stringify(grouped.category3, null, 4))
请注意,此json在结果数组中具有4个对象,其中cat1的2个,cat 2和cat3的1个。您可以在单独的文件中运行此代码以查看其工作方式。当然,您将从服务器获取json对象。我只是将其设置为演示。
然后设置状态:
this.setState({ grouped })
然后在render()
中,您仅显示具有以下项目的类别:
const menuBarButtons = Object.keys(this.state.grouped).map((category) => {
/* your jsx here */
return <MenuItem text={category} key={category} onClick={this.onClick} blah={blah}/>
/* or something , it's up to you */
})
我假设您正在根据当前选择的类别this.state.selected
显示项目。因此,在呈现菜单之后,您将执行以下操作:
const selectedCatItems = this.state.grouped[this.state.selected].map((item) => {
return <YourItem name={item.name} key={item.id} blah={blah} />
})
然后渲染它:
return (
<div className="app">
<MenuBar blah={blah}>
{menuBarButtons}
</Menubar>
<div for your item showing area>
{selectedCatItems}
</div>
</div>
)
此外,不要忘记更改您的onClick()
,以使其正确设置this.state.selected
状态。我相信您可以自己弄清楚。
希望有帮助。
PS:我之所以没有为您的问题写一个完整的复制/粘贴解决方案,仅仅是因为我不愿阅读和理解您的UI详细信息以及整个组件到组件数据传递的详细信息。
答案 1 :(得分:0)
只需使用结果中的list
函数将JSON输出转换为类似map
的对象,然后在状态上将其设置为MenuItems
,这就是您传递给函数的内容在render()
上。这样。
import React, { Component } from "react";
import ScrollMenu from "react-horizontal-scrolling-menu";
import "./menu.css";
// One item component
// selected prop will be passed
const MenuItem = ({ text, selected }) => {
return (
<div>
<div className="menu-item">{text}</div>
</div>
);
};
// All items component
// Important! add unique key
export const Menu = list =>
list.map(el => {
const { name } = el;
const { id } = el;
return <MenuItem text={name} key={id} />;
});
const Arrow = ({ text, className }) => {
return <div className={className}>{text}</div>;
};
export class Menucat extends Component {
state = {
selected: "0",
MenuItems: []
};
componentDidMount() {
fetch("menu.json")
.then(res => res.json())
.then(result => {
const items = result.results.map((el, idx) => {
return { name: el.category, id: idx };
});
this.setState({
isLoaded: true,
MenuItems: items
});
});
}
render() {
const { selected, MenuItems } = this.state;
// Create menu from items
const menu = Menu(MenuItems, selected);
return (
<div className="App">
<ScrollMenu
data={menu}
selected={selected}
onSelect={this.onSelect}
alignCenter={true}
tabindex="0"
/>
</div>
);
}
}
export default Menucat;
干杯!