javascript - React 使用 map 迭代嵌套数组/对象。渲染每个地图功能是否必须返回?
问题描述
我是反应新手。我正在构建一个小功能组件来呈现口袋妖怪的弱点。
它将存储在状态(pokemonState.types)中的口袋妖怪类型作为每种类型的对象数组,将类型与包含所有类型有效性的 JSON 文件进行比较(见下文)。
types_data.json
"electric": {
"attack": {
"double": ["flying", "water"],
"half": ["dragon", "electric", "grass"],
"zero": ["ground"]
},
"defense": {
"half": ["electric", "flying", "steel"],
"double": ["ground"],
"zero": []
}
为了获得我想要的数据,我需要进行多次迭代,并且我注意到我的组件仅在我指定 return 关键字并将我的元素包装在 HTML 标记中时才会呈现。
不呈现任何内容的函数(但 console.log 不返回未定义)
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>
);
}};
运行良好的功能:
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>
);
}};
我的问题是:
- 对于不渲染任何东西的函数,问题是我每次迭代后都不使用 return 对吗?
- 在这种情况下,我的第二个功能是好习惯吗?有没有我应该写的更干净的方式?
谢谢你的帮助。
解决方案
您的第一个功能不起作用的原因是您正在返回<p>{el}</p>
.
el
等于一个对象&你期待一个字符串。
具体来说,在这种情况下,它类似于{type:{name: "electric"}
如果您将那条线从 更改return <p>{el}</p>;
为return <p>{el.type.name}</p>;
,那么这会修复我们的内部.map
,因此您越来越接近。
但是,您还有第二个问题......外部.map
函数没有返回任何内容。您的typeEffectiveness
变量是我们最终要渲染的,并且该变量等于调用的结果allTypes.map
。当您的嵌套pokemonState.types.map
函数返回到父.map
函数时,您的父.map
函数没有返回语句。
最终,您正在渲染{typeEffectiveness}
,所以我们必须确保该变量是一个将渲染到 DOM 的反应元素数组。
还有其他几个小问题。也就是说,我们必须在 <p>{typeEffectiveness}</p>
此处删除段落标签,否则我们将得到嵌套p
标签,因为typeEffectiveness
列表中的每个项目都已包含在<p></p>
.
最后,您还应该将关键标签添加到列表项中。 <p key="{el.type.name}">{el.type.name}</p>
在此处深入了解有关列表和键的文档: https ://reactjs.org/docs/lists-and-keys.html
以下代码是您的第一个函数的调试版本。
我还在下面包含了您的部分功能的重构版本。types_data
当我们真的只关心我们的pokemonState
.
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>
推荐阅读
- pandas - 检查前列中是否存在列的值
- tableau-desktop - 有没有办法在 Tableau 中制作一个可以作为基于标准移动的参考线的计算字段?
- java - 二维双数组图像
- python - Plotly Dash 实现到 Raspberry pi,Window.Resize() 错误?
- perl - 在 Perl 中,如何在标量中创建“混合编码”字符串(或原始字节序列)?
- toad - 松鼠 - 当我选择一行然后编辑或删除时如何查看活动
- google-ads-api - 如何按更新日期过滤 Google Ads 广告系列?
- python - 在第二个函数中调用一个函数以将输出传递给第二个函数
- nestjs - 如何修复 Nest JS 框架中的 CORS 错误
- api - 将 QRCodeGenerator 添加到 API 后,收到 504 - Gateway Time-Out 错误