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 无法正常工作。