我很新,这是我的第一个问题,我希望其他人也会遇到类似的问题。
我正在接收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]
,网站将崩溃。
我希望在与此类似的问题在堆栈溢出之前被问到之前,我仍无法找到灵感或答案。
亲切的问候,
绵羊
答案 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>