React Fetch 返回不可用 __proto__ 个对象
React Fetch Returning Unusable __proto__ objects
我正在尝试访问位于以下 api 端点的 special_abilities
数组:http://www.dnd5eapi.co/api/monsters/1
这是我的容器组件:
import React, { Component } from 'react'
import { Link } from 'react-router';
import MonsterSpecialAbilities from '../components/MonsterSpecialAbilities'
class MonstersContainer extends Component {
constructor(props) {
super(props)
this.state = {
monster: {},
number: Math.floor((Math.random())*325)
}
this.handleRandomClick = this.handleRandomClick.bind(this)
}
componentDidMount() {
fetch(`http://www.dnd5eapi.co/api/monsters/${this.state.number}`)
.then(response => response.json())
.then(responseData => {
this.setState({ monster: responseData })
})
}
render() {
let spec_abilities;
spec_abilities = this.state.monster.special_abilities.map((ab) => {
return(
<MonsterSpecialAbilities
desc={ab.desc}
/>
)
})
return(
<div>
{this.state.monster.name}
{spec_abilities}
</div>
)
}
}
export default MonstersContainer
现在 .map
函数破坏了我的组件,我得到了控制台错误:Uncaught TypeError: this.state.monster.special_abilities.map is not a function
。我尝试通过访问 this.state.monster.special_abilities[0]
来访问数组,但是这个 returns 作为 null
,让我相信它是一个无效的数组。
我尝试创建一个状态名称 monster_special_ability
并按以下方式手动设置数组:
componentDidMount() {
fetch(`http://www.dnd5eapi.co/api/monsters/${this.state.number}`)
.then(response => response.json())
.then(responseData => {
this.setState({ monster: responseData })
this.setState({ monster_special_abilities: responseData.special_abilities })
})
}
我试过将调试器放在setState
函数中,然后在控制台中输入responseData.special_abilities
我想要的数组returns,但是设置状态后,似乎该数组不可用(它变成了 proto:object)
将您的怪物初始状态更改为 null
,并将您的渲染更改为:
render() {
if (!this.state.monster) {
return <div> Loading monster...</div>;
}
const spec_abilities = this.state.monster.special_abilities.map(ab =>
<MonsterSpecialAbilities desc={ab.desc} />
)
return (
<div>
{this.state.monster.name}
{spec_abilities}
</div>
)
}
如果您需要 monster
成为一个对象,您可以检查是否已经设置了 special_abilities
,而不是 monster
在 React 组件中使用 fetch 的一个常见做法是使用加载状态。最初将其设置为 false,一旦获取已解决,将其设置为 true。如果加载状态为真,您只渲染您的组件。所以你的最终代码应该如下所示:
class MonstersContainer extends Component {
constructor(props) {
super(props)
this.state = {
isDataLoaded: false,
monster: {},
number: Math.floor((Math.random())*325)
}
this.handleRandomClick = this.handleRandomClick.bind(this)
}
componentDidMount() {
fetch(`http://www.dnd5eapi.co/api/monsters/${this.state.number}`)
.then(response => response.json())
.then(responseData => {
this.setState({
isDataLoaded: true,
monster: responseData
})
}).catch(e => console.log(e));
}
render() {
const { isDataLoaded, monster } = this.state;
const monsterProps = { isDataLoaded, monster };
return <Monsters {...monsterProps} />
}
}
function MonsterSpecialAbilities(desc) {
return <div>desc</div>
}
function Monsters(props) {
const {isDataLoaded, monster} = props;
let spec_abilities;
if (isDataLoaded && monster.special_abilities) {
spec_abilities = monster.special_abilities.map((ab) =>
<MonsterSpecialAbilities
desc={ab.desc}
/>
);
}
return (isDataLoaded && spec_abilities && monster.name) ? (
<div>
{monster.name}
{spec_abilities}
</div>
): <div>loading monster data...</div>;
}
在 jsbin 上观看直播。
请注意,提取可能会失败,您还需要采取一些措施。您可以添加另一个名为 errorMessage
的状态来显示错误消息。在您的情况下,请确保您的主机在 http 上是 运行 而不是 https,因为使用 https 获取时 url 无法正常工作。
我正在尝试访问位于以下 api 端点的 special_abilities
数组:http://www.dnd5eapi.co/api/monsters/1
这是我的容器组件:
import React, { Component } from 'react'
import { Link } from 'react-router';
import MonsterSpecialAbilities from '../components/MonsterSpecialAbilities'
class MonstersContainer extends Component {
constructor(props) {
super(props)
this.state = {
monster: {},
number: Math.floor((Math.random())*325)
}
this.handleRandomClick = this.handleRandomClick.bind(this)
}
componentDidMount() {
fetch(`http://www.dnd5eapi.co/api/monsters/${this.state.number}`)
.then(response => response.json())
.then(responseData => {
this.setState({ monster: responseData })
})
}
render() {
let spec_abilities;
spec_abilities = this.state.monster.special_abilities.map((ab) => {
return(
<MonsterSpecialAbilities
desc={ab.desc}
/>
)
})
return(
<div>
{this.state.monster.name}
{spec_abilities}
</div>
)
}
}
export default MonstersContainer
现在 .map
函数破坏了我的组件,我得到了控制台错误:Uncaught TypeError: this.state.monster.special_abilities.map is not a function
。我尝试通过访问 this.state.monster.special_abilities[0]
来访问数组,但是这个 returns 作为 null
,让我相信它是一个无效的数组。
我尝试创建一个状态名称 monster_special_ability
并按以下方式手动设置数组:
componentDidMount() {
fetch(`http://www.dnd5eapi.co/api/monsters/${this.state.number}`)
.then(response => response.json())
.then(responseData => {
this.setState({ monster: responseData })
this.setState({ monster_special_abilities: responseData.special_abilities })
})
}
我试过将调试器放在setState
函数中,然后在控制台中输入responseData.special_abilities
我想要的数组returns,但是设置状态后,似乎该数组不可用(它变成了 proto:object)
将您的怪物初始状态更改为 null
,并将您的渲染更改为:
render() {
if (!this.state.monster) {
return <div> Loading monster...</div>;
}
const spec_abilities = this.state.monster.special_abilities.map(ab =>
<MonsterSpecialAbilities desc={ab.desc} />
)
return (
<div>
{this.state.monster.name}
{spec_abilities}
</div>
)
}
如果您需要 monster
成为一个对象,您可以检查是否已经设置了 special_abilities
,而不是 monster
在 React 组件中使用 fetch 的一个常见做法是使用加载状态。最初将其设置为 false,一旦获取已解决,将其设置为 true。如果加载状态为真,您只渲染您的组件。所以你的最终代码应该如下所示:
class MonstersContainer extends Component {
constructor(props) {
super(props)
this.state = {
isDataLoaded: false,
monster: {},
number: Math.floor((Math.random())*325)
}
this.handleRandomClick = this.handleRandomClick.bind(this)
}
componentDidMount() {
fetch(`http://www.dnd5eapi.co/api/monsters/${this.state.number}`)
.then(response => response.json())
.then(responseData => {
this.setState({
isDataLoaded: true,
monster: responseData
})
}).catch(e => console.log(e));
}
render() {
const { isDataLoaded, monster } = this.state;
const monsterProps = { isDataLoaded, monster };
return <Monsters {...monsterProps} />
}
}
function MonsterSpecialAbilities(desc) {
return <div>desc</div>
}
function Monsters(props) {
const {isDataLoaded, monster} = props;
let spec_abilities;
if (isDataLoaded && monster.special_abilities) {
spec_abilities = monster.special_abilities.map((ab) =>
<MonsterSpecialAbilities
desc={ab.desc}
/>
);
}
return (isDataLoaded && spec_abilities && monster.name) ? (
<div>
{monster.name}
{spec_abilities}
</div>
): <div>loading monster data...</div>;
}
在 jsbin 上观看直播。
请注意,提取可能会失败,您还需要采取一些措施。您可以添加另一个名为 errorMessage
的状态来显示错误消息。在您的情况下,请确保您的主机在 http 上是 运行 而不是 https,因为使用 https 获取时 url 无法正常工作。