如何从 JSON 映射嵌套数组?
Posted
技术标签:
【中文标题】如何从 JSON 映射嵌套数组?【英文标题】:How can I map a nested array from JSON? 【发布时间】:2018-03-09 08:43:09 【问题描述】:请耐心等待,我不善言辞,在这里,我将尽力解释我在映射数组中的嵌套数据时遇到的问题,我猜这个术语将被称为“从本地 API 获取数据ReactJS”下面这段代码是data.js中的数据作为“本地API”
export default[
name: "John Doe",
position: "developer",
experiences: [
id: 0,
job:"developer 1",
period: "2016-2017",
description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laudantium nesciunt recusandae unde. Qui consequatur beatae, aspernatur placeat sapiente non est!"
,
id: 1,
job:"developer 2",
period: "2015-2016",
description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laudantium nesciunt recusandae unde. Qui consequatur beatae, aspernatur placeat sapiente non est!"
,
id: 2,
job:"developer 3",
period: "2014-2015",
description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laudantium nesciunt recusandae unde. Qui consequatur beatae, aspernatur placeat sapiente non est!"
]
]
下面的代码展示了 ReactJS 中的 index.js 和 App.js 两个组件文件
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App'
import data from './data/dataJS';
ReactDOM.render(
<App data=data />,
document.getElementById('root'));
App.js
import React, Component from 'react';
import './App.css';
class App extends Component
render()
const data = this.props;
const resume = data.map(info =>
//console log
console.log(info.name);
console.log(info.position);
console.log(info.experiences);
console.log(info.experiences.job);
//browser render
return (
<div>
info.name
<br/>
info.position
</div>
)
);
);
return (
<div>
<p>resume</p>
</div>
);
到目前为止,我能够从浏览器 console.log 中获取已确认的数据,并将两个数据 info.name
渲染到 John Doe 和 info.position
渲染到 developer 没问题。
现在,如果我在 info.position 下添加此字符串 <li key="experience.id">info.experiences.job</li>
,我会收到错误消息。
对象作为 React 子对象无效(找到:对象与键 id, job, period, description)。如果您打算渲染一组子项,请改用数组。
我假设,我设置数组的方式不正确。但是info.experiences
的 console.log 显示了 (3) 组经验的结果。但是控制台登录info.experiences.job
显示未定义。但是我无法弄清楚问题是什么,可能出了什么问题?
我花了两天时间试图找到解决方案,但我没有任何运气。
有什么建议吗?
【问题讨论】:
info.experiences
是一个数组。 console.log(info.experiences)
应该告诉你。因此,要访问 job
属性,您必须执行 info.experiences[0].job
或类似的操作。
info.experiences[i].job
为什么你的App
渲染中有 2 个return
?
@Sag1v 一个在data.map
内部。它将resume
变成了一个元素数组。
你有语法错误,第一次返回后你关闭了render
函数
【参考方案1】:
这里有几件事要解决:
您在render
函数中遇到语法错误,在第一个
return
你关闭了 render
函数体,因此你不能
到达第二个return
(它甚至不应该渲染和抛出
错误)。
您试图在您的密钥中引用一个对象?你用了一个字符串。 无论如何,键对于他们的兄弟姐妹应该是唯一的DOCS。
<li key="experience.id">info.experiences.job</li>
这应该是(但请记住我们还没有完成!):
<li key=experience.id>info.experiences.job</li>
experience
未定义,我猜你想循环遍历
experiences
数组:
info.experiences.map(experience => <li key=experience.id>experience.job</li>)
无论如何,这里是一个运行和工作的例子:
const data = [
name: "John Doe",
position: "developer",
experiences: [
id: 0,
job: "developer 1",
period: "2016-2017",
description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laudantium nesciunt recusandae unde. Qui consequatur beatae, aspernatur placeat sapiente non est!"
,
id: 1,
job: "developer 2",
period: "2015-2016",
description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laudantium nesciunt recusandae unde. Qui consequatur beatae, aspernatur placeat sapiente non est!"
,
id: 2,
job: "developer 3",
period: "2014-2015",
description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laudantium nesciunt recusandae unde. Qui consequatur beatae, aspernatur placeat sapiente non est!"
]
]
class App extends React.Component
render()
const data = this.props;
const resume = data.map(info =>
//browser render
return (
<div>
info.name
<ul>
info.experiences.map(experience => <li key=experience.id>experience.job</li>)
</ul>
info.position
</div>
);
);
return <div><p>resume</p></div>;
ReactDOM.render(
<App data=data />,
document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
编辑 作为您的 cmets 的后续行动:
我几乎从未遇到任何错误,除非我尝试分配它 在嵌套数组上
对于您在App.js
的render
方法中的代码:
render()
// console.log(this.props.name)
const data = this.props;
const resume = data.map((info) =>
return (
<div>
info.name
info.experiences.map((experience, idx)=>
<div >
<div key=experience.id >experience.job</div>
</div>)
info.position
</div>
)
);
你有 2 个问题:
在第一次循环迭代中,您应该将一个键传递给根元素 好吧,不仅是第二个循环。
const resume = data.map((info, key) =>
return (
<div key=key>
info.name
// ...
在第二个循环中,您将键传递给子元素,而不是 此循环的父元素:
info.experiences.map((experience, idx)=>
<div >
<div key=experience.id >experience.job</div>
</div>)
键应该在根元素而不是第二个元素上:
info.experiences.map((experience, idx) =>
<div key=experience.id>
<div>experience.job</div>
</div>)
工作示例:
const data = [
id: "resume",
name: "John Doe",
position: "developer",
experiences: [
id: 0,
job: "developer 1",
period: "2016-2017",
description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laudantium nesciunt recusandae unde. Qui consequatur beatae, aspernatur placeat sapiente non est!"
,
id: 1,
job: "developer 2",
period: "2015-2016",
description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laudantium nesciunt recusandae unde. Qui consequatur beatae, aspernatur placeat sapiente non est!"
,
id: 2,
job: "developer 3",
period: "2014-2015",
description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laudantium nesciunt recusandae unde. Qui consequatur beatae, aspernatur placeat sapiente non est!"
]
]
class App extends React.Component
render()
// console.log(this.props.name)
const data = this.props;
const resume = data.map((info, i) =>
return (
<div key=i>
info.name
info.experiences.map((experience, idx) =>
<div key=experience.id>
<div>experience.job</div>
</div>)
info.position
</div>
)
);
return (
<div>
resume
</div>
);
ReactDOM.render(<App data=data />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
奖金 至于这条评论:
我会使用 codepen,但意识到但无法创建 两个文件,即 index.js 和 App.js
您可以使用code sandbox,它非常适合反应。 这是一个工作示例,您的代码位于单独的文件link。
【讨论】:
它有效,但仍然遇到密钥 ID 问题。是的,带有“”的字符串已被删除。我使用 experience.id 任何建议。 你说的“但仍然遇到key id问题”是什么意思?什么样的问题?不过它在这里工作 抱歉不清楚...按照您的建议更正后,它解决了问题。我可以在页面上看到 array.map 的数据。同时,浏览器的 console.log 会显示带有唯一 ID 的警告。 --> “proxyConsole.js:54 警告:数组或迭代器中的每个孩子都应该有一个唯一的“键”道具。”看来这与 key=experience.id 未被识别有关。 @sirrus React 想要一种单独跟踪每个 DOM 元素的方法,因此您需要一个key
属性。简单。只需使用 map
info.experiences.map((experience, idx) => <li key=experience.id key=idx>experience.job</li>
中内置的索引号参数
@Sag1v - 现在我可以清楚地看到我的问题是什么,我已经记下了它以备将来使用。我明白,任何时候我想进行循环迭代都应该始终在任何元素上分配唯一键作为一个好习惯。如果不需要,React 不会抱怨。至于您分享的奖励功能。这是我不知道的事情,对我有很大帮助,现在我可以在反应同行之间共享代码。感谢大家的努力和时间。向你致敬。以上是关于如何从 JSON 映射嵌套数组?的主要内容,如果未能解决你的问题,请参考以下文章
restkit 映射嵌套数组为空(带有 json 响应的嵌套 restkit 请求)
如何将具有嵌套对象的复杂 json 文件映射到 java 对象?