2017-06-15 41 views
0

我试图去的special_abilities阵列在下面的API端点:http://www.dnd5eapi.co/api/monsters/1反应取返回不可用__proto__ obejcts

这里是我的容器组件:

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]访问数组,但这返回为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到控制台返回数组我想要的,但状态设置后,似乎阵列不可用(它变成原型:对象)

任何帮助,将不胜感激!我很乐意澄清其他事情。

+0

使用异步数据时要小心,在尝试使用它之前检查它是否已经可用:'this.state.monster.special_abilities'可能没有在第一次渲染中定义,但是在您获取它之后,它是 – BravoZulu

+0

@BravoZulu ,我确实通过放入if语句来检查状态是否为空。我在浏览器控制台中得到了相同的回复。 –

+0

你的陈述是什么?在下面检查我的答案,它可能会帮助你 – BravoZulu

回答

0

使用提取反应组件时的一种常见做法是使用加载状态。最初将其设置为false,一旦解析完成,将其设置为true。如果加载状态为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和NOT https上,因为当使用https获取时,提取url不起作用。

+0

因此它显示加载程序,但isDataLoaded不在执行在componentsnetDidMount期间。然而怪物状​​态正在改变。 –

+0

检查我更新的答案。 –

+0

它没有去捕捉,同样的问题;怪物获取正确,但'isDataLoaded'仍然是假的 –

0

改变你的怪物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集,insted的的monster