[英]React iterate nested arrays/objects with map. Is return mandatory to render each map function?
I'm new to React.我是 React 的新手。 I'm building a small function component that renders the weaknesses of a Pokemon.
我正在构建一个小的功能组件来呈现 Pokemon 的弱点。
It takes the type of the Pokemon stored in the state (pokemonState.types) as an array of objects for each type, compare the type to a JSON file containing all the type effectiveness (see below).它将存储在状态 (pokemonState.types) 中的 Pokemon 类型作为每个类型的对象数组,将类型与包含所有类型有效性的 JSON 文件进行比较(见下文)。
types_data.json types_data.json
"electric": {
"attack": {
"double": ["flying", "water"],
"half": ["dragon", "electric", "grass"],
"zero": ["ground"]
},
"defense": {
"half": ["electric", "flying", "steel"],
"double": ["ground"],
"zero": []
}
To get the data I want, I need to do several iterations and I noticed my component only renders when I specify the return keyword and wrap my element in a HTML tag.为了获得我想要的数据,我需要进行多次迭代,我注意到我的组件仅在我指定 return 关键字并将我的元素包装在 HTML 标记中时才会呈现。
Function that doesn't render anything (but console.log doesn't return undefined)不呈现任何内容的函数(但 console.log 不返回 undefined)
const pokemonTypeChart = () => {
if (!_.isEmpty(pokemonState)) {
const allTypes = Object.entries(types_data);
const typeEffectiveness = allTypes.map(([key, value]) => {
pokemonState.types.map((el) => {
if (el.type.name === key) {
console.log(key, value);
return <p>{el}</p>;
}
});
});
return (
<div>
<h1>Test</h1>
<p>{typeEffectiveness}</p>
</div>
);
}};
Function that works well:运行良好的功能:
const pokemonTypeChart = () => {
if (!_.isEmpty(pokemonState)) {
const allTypes = Object.entries(types_data);
return (
<div>
<h1>Type Effectiveness</h1>
{allTypes.map(([key, value]) => {
return (
<>
{pokemonState.types.map((el, i) => {
if (el.type.name === key)
return <h3 key={i}>{value.defense.double}</h3>;
})}
</>
);
})}
</div>
);
}};
My question are:我的问题是:
Thanks for your help.谢谢你的帮助。
The reason why your first function isn't working is that you are returning <p>{el}</p>
.您的第一个函数不起作用的原因是您正在返回
<p>{el}</p>
。
el
is equal to an object & you are expecting a string. el
等于一个对象 & 你期待一个字符串。
Specifically, in this case, it is something like {type:{name: "electric"}
具体来说,在这种情况下,它类似于
{type:{name: "electric"}
If you change that line from return <p>{el}</p>;
如果你从
return <p>{el}</p>;
to return <p>{el.type.name}</p>;
return <p>{el.type.name}</p>;
, then that fixes our inner .map
, so you are getting closer. ,然后修复我们内部的
.map
,所以你越来越近了。
However, you've also got a second problem... the outer .map
function is not returning anything.但是,您还有第二个问题……外部
.map
函数没有返回任何内容。 Your typeEffectiveness
variable is what we're ultimately rendering, and that variable is equal to the result from calling allTypes.map
.您的
typeEffectiveness
变量是我们最终要渲染的变量,该变量等于调用allTypes.map
的结果。 While your nested pokemonState.types.map
function is getting returned to the parent .map
function, your parent .map
function does not have a return statement.当您嵌套的
pokemonState.types.map
函数返回给父.map
函数时,您的父.map
函数没有 return 语句。
Ultimately, you are rendering {typeEffectiveness}
, so we've gotta make sure that variable is an array of react elements that will render to the DOM.最终,您正在渲染
{typeEffectiveness}
,因此我们必须确保该变量是一个将渲染到 DOM 的 react 元素数组。
There were a couple other minor issues as well.还有一些其他的小问题。 Namely, we have to remove the paragraph tags
<p>{typeEffectiveness}</p>
here or we'd end up with nested p
tags, since each item in the typeEffectiveness
list is already enclosed in <p></p>
.也就是说,我们必须在这里删除段落标签
<p>{typeEffectiveness}</p>
否则我们最终会得到嵌套的p
标签,因为typeEffectiveness
列表中的每个项目都已经包含在<p></p>
。
Finally, you should add key tags to your list items as well.最后,您还应该将关键标签添加到您的列表项中。
<p key="{el.type.name}">{el.type.name}</p>
Dig into the documentation on Lists & Keys here: https://reactjs.org/docs/lists-and-keys.html在此处深入了解列表和键的文档: https : //reactjs.org/docs/lists-and-keys.html
The following code is a debugged version of your first function.以下代码是您的第一个函数的调试版本。
I also included a refactored version of your section function below.我还在下面包含了您的部分功能的重构版本。 It would be fairly inefficient to map through the entire
types_data
object entries, when we really only care about the types present in our pokemonState
, so take a look at my approach to that below as well.当我们真的只关心我们的
pokemonState
存在的类型时,映射整个types_data
对象条目将是相当低效的,所以看看我在下面的方法。
const e = React.createElement; const pokemonState ={types: [{type:{name: "electric"}}]}; let types_data = { "electric": { "attack": { "double": ["flying", "water"], "half": ["dragon", "electric", "grass"], "zero": ["ground"] }, "defense": { "half": ["electric", "flying", "steel"], "double": ["ground"], "zero": [] } } }; const PokemonTypeChart = () => { if (!_.isEmpty(pokemonState)) { const allTypes = Object.entries(types_data); const typeEffectiveness = allTypes.map(([key, value]) => { return (pokemonState.types.map((el) => { if (el.type.name === key) { return ( <p key="{el.type.name}">{el.type.name}</p> ); } })); }); return ( <div> <h1>Test</h1> {typeEffectiveness} </div> ); }}; const domContainer = document.querySelector('#pokemon'); ReactDOM.render(e(PokemonTypeChart), domContainer);
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script> <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script> <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/underscore@1.13.1/underscore-umd-min.js"></script> <div id="pokemon"></div>
const e = React.createElement; const pokemonState ={types: [{type:{name: "electric"}}]}; let types_data = { "electric": { "attack": { "double": ["flying", "water"], "half": ["dragon", "electric", "grass"], "zero": ["ground"] }, "defense": { "half": ["electric", "flying", "steel"], "double": ["ground"], "zero": [] } } }; const PokemonChart = () => { if (!_.isEmpty(pokemonState)) { const plistItems = pokemonState.types.map((item) => types_data[item.type.name].defense.double.map((i) => <p key={i}>{i}</p> )); return ( <div> <h1>Type Effectiveness</h1> {plistItems} </div> ); }}; const domContainer = document.querySelector('#pokemon'); ReactDOM.render(e(PokemonChart), domContainer);
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script> <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script> <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/underscore@1.13.1/underscore-umd-min.js"></script> <div id="pokemon"></div>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.