【问题标题】:React map function: how to output content of all nested arrays at once?React map 函数:如何一次输出所有嵌套数组的内容?
【发布时间】:2019-09-15 21:03:05
【问题描述】:

我的数据是一个带有键值对的对象,然后是一些带有字符串的数组(“skill_1”和“skill_2”):

const HeroDescriptions = [
  {
    id: "ana",
    name: "Ana",
    role: "Support",
      skill_1: [
        "Biotic Rifle",
        "Damage: 70",
        "Healing: 75"
      ],
      skill_2: [
        "Biotic Grenade",
        "Damage: 60",
        "Healing: 100"
      ]
    }
  ]

我这样输出到 JSX:

const content = description.map(item => (
    <div key={item.id}>
      <h1>{item.name}</h1>
      <h2>Role: {item.role}</h2>
      <hr />
      <ul>
        {description[0].skill_1.map((skill, index) => (
          <li key={index}>{skill}</li>
        ))}
      </ul>
    </div>
  ));

  return (
    <div>
      <ul>{content}</ul>
    </div>
  );
};

我想修改这个sn-p:

{description[0].skill_1.map((skill, index) => (
   <li key={index}>{skill}</li> 

我如何遍历所有嵌套的技能数组,以便我的代码可以重用并且可以工作,例如4阵有技能?

【问题讨论】:

  • 尝试使用不同的数据格式:{ "skills": [ { "name": "rifle", "damage": 70, "healing": 50 }, { "name": "knife", "damage": 15, "healing": 10 }] } 会更有意义。然后你不必知道一个英雄在模板中有多少技能,你可以像 map() 描述一样 map() 技能。另一个优点是在计算射击时您不需要将“70 伤害”解析为整数。
  • 您可以使用Object.entriesArray.filter 与正则表达式/^skill_.*/,最后当然是您的Array.map 或者像@Shilly 指出的那样改变您的结构.. :)跨度>
  • 为什么不使用数组:skills: [ [ "Biotic Rifle", "Damage: 70", "Healing: 75" ], [ "Biotic Grenade", "Damage: 60", "Healing: 100" ] ]
  • 如果技能是具有键值对而不是数组的对象,方法将如何改变?我尝试遵循@Shilly 的方法,但每个角色的技能可能不同。例如。治疗并不总是可用的。我想知道即使不同英雄的键不同,是否可以映射所有技能
  • 守望先锋中无法使用任何技能治疗的角色,所有技能的治疗量为 0。关键是治疗应该是技能对象的属性,即使它是零。在所有内容上都有一个固定的键列表,即使它们的值是 0 或 null 或未定义,这意味着您可以对这些属性进行硬编码,而不必使用 Object.keys() 之类的东西来检查对象上是否有可用的键。所以那么“映射所有技能,即使它们具有不同的键”的问题不再存在,因为所有东西都有相同的键,只是具有不同的值。

标签: javascript arrays reactjs jsx


【解决方案1】:

使用您现有的数据结构,您可以使用spread 语法将技能一起捕获,然后使用getSkills 方法,reduce 在每个对象的值上组合数组,然后map 在上面准备生成您的最终技能列表。

class App extends React.Component {

  getSkills(skills) {
    return Object.values(skills).reduce((acc, skillset) => {
      return [...acc, ...skillset];
    }, []).map(skill => <li>{skill}</li>);
  }

  render() {
 
   const { descriptions } = this.props;
 
   return (

     descriptions.map(params => {
       const { id, name, role, ...skills } = params;
       return (
         <div key={id}>
         <h1>{name}</h1>
         <h2>Role: {role}</h2>
         <hr />
         <ul>
           {this.getSkills(skills)}
         </ul>
         </div>
       );
     })
   );
  }
}

const descriptions = [{"id":"ana","name":"Ana","role":"Support","skill_1":["Biotic Rifle","Damage: 70","Healing: 75"],"skill_2":["Biotic Grenade","Damage: 60","Healing: 100"]}];

ReactDOM.render(
  <App descriptions={descriptions} />,
  document.querySelector('#app')
);
.category { margin: 1em; }
h1 { font-size: 1em; font-weight: 600; }
h2 { font-size: 0.9em; font-weight: 600; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>

【讨论】:

  • 感谢您的回答。我实施了您的解决方案。我在一个带有钩子的功能组件中,所以我省略了“this”关键字
【解决方案2】:

您可以将skill_x 属性提取到数组中:

const HeroDescriptions = [{
		id: "ana",
		name: "Ana",
		role: "Support",
		skill_1: [
			"Biotic Rifle",
			"Damage: 70",
			"Healing: 75"
		],
		skill_2: [
			"Biotic Grenade",
			"Damage: 60",
			"Healing: 100"
		]
	}
];

({id, name, role, ...skills} = HeroDescriptions[0]);

console.log(Object.values(skills));
.as-console-wrapper {
  max-height: 100% !important;
  top: 0;
}

我同意上述 cmets,将这些属性重新格式化为如下所示的内容会更有意义:

{
    skill: 'Biotic Rifle',
    damage: 70,
    Healing: 75
}

【讨论】:

    【解决方案3】:

    你好守望先锋玩家:)

    如果你想遍历一个对象的键,你可以使用 Object.keys 方法,描述为here

    你的代码块会变成:

    Object.keys(item)
      .filter(key => ['id', 'name', 'role'].indexOf === -1))  // filter out unrelated keys
      .map(skillKey => item[skillKey])
      .map(skillArr => <li key={skillArr[0]}>{skillArr.join(', ')}</li>)
    

    P.S:您的数据对象格式不正确。最好有另一个名为“技能”的字段并循环遍历它们

    【讨论】:

    • 如果你使用Object.entries..Object.entries(item).filter(([skillKey]) =&gt; ...).map(([_, skillArr]) =&gt; ...,你可以避免你的双重map
    • 我觉得一次只使用物品或钥匙会更清楚。尤其是当您有 2,3 个地图/过滤任务时
    猜你喜欢
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    • 2020-10-27
    • 2011-06-06
    • 1970-01-01
    • 2018-05-09
    • 2018-11-15
    • 1970-01-01
    相关资源
    最近更新 更多