javascript - Iterate through nested objects
问题描述
I am creating a React app and have the following list:
const list = [
{
id: '1',
task: 'task 1',
activities: [{
'Google': [
{url: 'https://www.google.com'},
{visited: false}
],
'Yahoo': [
{url: 'https://www.yahoo.com'},
{visited: false}
],
'Bing': [
{url: 'https://www.bing.com'},
{visited: false}
]
}],
visitedAll: false
},
{
id: '2',
task: 'task 2',
activities: [{
'Facebook': [
{url: 'https://www.facebook.com'},
{visited: false}
],
'Instagram': [
{url: 'https://www.instagram.com'},
{visited: false}
],
'Twitter': [
{url: 'https://www.twitter.com'},
{visited: false}
]
}],
visitedAll: false
}
];
I am iterating through the list like so:
<ul>
{list.map(item => (
<li key={item.id}>
{item.task}
<ul>
{Object.keys(item.activities[0]).map((act, i) => <li key={i}>{act}</li>)}
</ul>
</li>
))}
</ul>
Which will produce the following output:
-
task 1
- Yahoo
- Bing
-
task 2
- How can I wrap the submenu list items with their corresponding anchors?
- How do I add an onClick event which will set the
visited
key totrue
for each item?
解决方案
您可以首先activities
使用方法将属性修改为一个对象reduce
,然后您可以为子项创建单独的组件,其中每个子项都具有visited
属性的状态。
const {useState} = React;
const list = [{"id":"1","task":"task 1","activities":[{"Google":[{"url":"https://www.google.com"},{"visited":false}],"Yahoo":[{"url":"https://www.yahoo.com"},{"visited":false}],"Bing":[{"url":"https://www.bing.com"},{"visited":false}]}],"visitedAll":false},{"id":"2","task":"task 2","activities":[{"Facebook":[{"url":"https://www.facebook.com"},{"visited":false}],"Instagram":[{"url":"https://www.instagram.com"},{"visited":false}],"Twitter":[{"url":"https://www.twitter.com"},{"visited":false}]}],"visitedAll":false}]
.map(({activities, ...rest}) => ({
...rest, activities: activities.reduce((r, e) => Object.assign(r, e), {})
}))
const SubListItem = props => {
const {data, name} = props;
const [visited, setVisited] = useState(data[1].visited);
const toggle = event => {
event.preventDefault();
setVisited(!visited);
}
return <li>
<a style={{color: visited ? "green" : ''}}
onClick={toggle}
href={data[0].url}>{name}</a>
</li>
}
const List = ({data}) => <ul>
{data.map(item => <li key={item.id}>
<a href="">{item.task}</a>
<ul>{Object.keys(item.activities).map(act => (
<SubListItem key={act} name={act} data={item.activities[act]} />
))}</ul>
</li>)}
</ul>
ReactDOM.render(<List data={list} />, document.querySelector("#app"))
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
transition: all 0.2s;
}
li {
margin: 8px 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="app"></div>
推荐阅读
- angular - 在Angular中重复自动单击按钮的脚本
- php - 从mysql中的不同表中提取两列
- reactjs - 我们可以通过在组件中使用 componentDidCatch 来捕获操作引发的异常吗?
- google-maps - 如何在 iOS 和 android 上以 react native 实现谷歌地图?
- jquery - 重新连接到 Nodejs socket.io 服务器
- linux-kernel - 在 Linux 内核中向用户空间公开一个额外的标头
- java - 如何使用 O(n) 时间复杂度算法查找有效子字符串的数量
- binary - 将二进制文件从特定地址点填充到地址中的另一个特定地址点
- jquery - Jquery:更改 div 的内容会修改其行为
- typescript - Vue + webpack + TS:生成声明时找不到.vue.d.ts