我无法访问对象数组中的嵌套对象

时间:2020-03-23 10:58:30

标签: javascript json reactjs api

我很新,这是我的第一个问题,我希望其他人也会遇到类似的问题。

API url

我正在接收api数据并转换为JSON格式。由此,我可以访问对象(每个怪物)中的键和值

hit_points: 17   (key: value)
hit_dice: "5d6"   (key: value)
speed: {fly: 40, walk: 20}   (object)

special_abilities: Array(1)
  0:
   desc: "some text"
   name: "One with Wind"

我能够访问special_abilities[0].name,在这种情况下,我会返回"One with Wind"

当一个怪物只有1个能力时,我得到的是一种以上的能力,如何显示全部3种而不使脚本崩溃,我无法解决该怎么办。

import React, {useState, useEffect} from 'react';
import './App.css';

function currentMonster({match}) {
    const [item, setItem] = useState([]);
    useEffect (() => {
        fetchMonster();
    }, []);

const fetchMonster  = async () => {
    const mob = match.params.id.toLowerCase();
    const fetchMonster = await fetch(`https://api.open5e.com/monsters/${mob}/?format=json`)
    const monster = await fetchMonster.json();
    setItem(monster)
    console.log(monster);
// const abilities = monster.special_abilities[0].name
}
    return (
            <div>
                <h1>{item.name}</h1>
                <p>Size: {item.size}</p>
                <p>Race: {item.type}</p>
                <p>Alignment: {item.alignment}</p>
                <p>Armor Class: {item.armor_class}</p>
                <p>Hit points: {item.hit_points}</p>
                <p>Hit dice: {item.hit_dice}</p>
                <p>Strength: {item.strength}</p>
                <p>Dexterity: {item.dexterity}</p>
                <p>Constitution: {item.constitution}</p>
                <p>Intelligence: {item.intelligence}</p>
                <p>Wisdom: {item.wisdom}</p>
                <p>Charisma: {item.charisma}</p>
                <p>Senses: {item.senses}</p>
                <p>CR: {item.challenge_rating}</p>
            </div>
        )
    }


  export default currentMonster;

这是我当前拥有的代码,我希望在列表上添加另一个<p></p>,以显示怪物的每种特殊能力和描述,而当它们具有一个以上能力时,这些怪物也会同时出现。

在问我尝试过之前:

const [ability, setAbility] = useState([]);
setAbility(monster.special_abilities[0])
and then <p>{ability.name}</p>

这对一个怪物有效,但是如果该怪物具有更多能力,那么我将看不到它们。如果怪物的能力少于两个,并且我说[0][1][2],网站将崩溃。

我希望在与此类似的问题在堆栈溢出之前被问到之前,我仍无法找到灵感或答案。

亲切的问候,

绵羊

1 个答案:

答案 0 :(得分:1)

这里是一个示例,说明当current发生变化时如何获取怪物,您可以从current获取match.params.id,但我不想做一个路由示例进行演示。请注意,我使用的是monster.slug,这可能与怪物名称不同。您还应该使用monster.slug,因为这就是api的用途。

确保current是您效果的依赖项,以便它在更改时会重新运行。我认为您没有正确设置开发环境,因为您显示的代码缺少依赖项,并且您的编辑器should have warned you

const { useState, useEffect } = React;

const App = () => {
  const [current, setCurrent] = useState('aatxe');
  //you can do:
  //const current = match.params.id.toLowerCase();
  const [item, setItem] = useState(null);
  useEffect(() => {
    //SO code snippet doesn't have recent babel, so no
    // async await support in snippet code, changed to
    // promise
    const fetchMonster = () =>
      fetch(
        `https://api.open5e.com/monsters/${current}/?format=json`
      )
        .then(response => response.json())
        .then(setItem);
    fetchMonster();
  }, [current]);

  return (
    <div>
      <select
        value={current}
        onChange={e => setCurrent(e.target.value)}
      >
        <option value="aatxe">Aatxe</option>
        <option value="aboleth">Aboleth</option>
      </select>
      {item && (
        <div>
          <h1>{item.name}</h1>
          <ul>
            {item.special_abilities.map(
              (ability, index) => (
                <li key={index}>{ability.name}</li>
              )
            )}
          </ul>
        </div>
      )}
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById('root'));
<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="root"></div>