【问题标题】:Call API from React从 React 调用 API
【发布时间】:2017-09-14 15:36:06
【问题描述】:

我正在尝试让 React 从 Django Rest Framework API 获取 JSON。链接写成http://127.0.0.1:8000/band/api/1/?format=json,结构如下:

{
id: 1,
name: "Muse",
date_added: "2017-04-17",
image: "https://upload.wikimedia.org/wikipedia/commons/a/a3/Muse_melbourne28012010.jpg",
bio: "Muse are an English rock band from Teignmouth, Devon, formed in 1994. The band consists of Matt Bellamy (lead vocals, guitar, piano, keyboards), Chris Wolstenholme (bass guitar, backing vocals, keyboards) and Dominic Howard (drums, percussion)."
}

我的反应是这样写的:

class ItemLister extends React.Component {
    constructor() {
    super();
         this.state={items:[]};
  }
  componentDidMount(){
    fetch(`http://127.0.0.1:8000/band/api/1/?format=json`)
        .then(result=>result.json())
        .then(items=>this.setState({items}))
        setTimeout(() => console.log(this.state.items), 2000)
  }
  render() {
    return(
        <ul>
          {this.state.items.length ?
            this.state.items.map(item=><li key={item.id}>{item.name}</li>)
            : <li>Loading...</li>
          }
      </ul>
   )
  }
}

ReactDOM.render(
  <ItemLister />,
  document.getElementById('container')
);

HTML 容器 div 停留在 loading...,控制台显示没有错误。我知道它与 JSON 有关,但无法弄清楚它是什么,感谢任何帮助!

编辑:

按照 m_callens 的建议添加以下内容后:

setTimeout(() => console.log(this.state.items), 2000)

控制台返回我确实想要获取的对象,但它仍然没有呈现在页面上。

Object {id: 1, name: "Muse", date_added: "2017-04-17", image: "https://upload.wikimedia.org/wikipedia/commons/a/a3/Muse_melbourne28012010.jpg", bio: "Muse are an English rock band from Teignmouth, Dev…eyboards) and Dominic Howard (drums, percussion)."}

【问题讨论】:

  • 你真的得到数据了吗?尝试注销第二个中的项目。然后
  • @WilomGfx 我添加了,console.log(this.items) 在第二个 .then 下面,它说未定义。
  • 那么你没有从 api 接收数据,确保它在服务器端工作。
  • 尝试使用静态 .json 文件,如果可行,则说明您的 API 有问题
  • 你做错了超时。做setTimeout(() =&gt; console.log(this.state.items), 2000)

标签: javascript json django reactjs django-rest-framework


【解决方案1】:

所以经过漫长的日志记录和调试过程,我想我已经找到了问题所在。

您的初始状态是将items 属性创建为array,因此您尝试将每个项目映射到&lt;li&gt; 以呈现到您的用户界面,但是您从@ 获得的值987654326@ 调用并将this.state.items 重新分配给不是array,而是一个简单的对象。因此,当您尝试 map 对象时,它会失败,这也解释了为什么您的 length 条件总是失败。

不要在第二次 .then 处理中直接重新分配 items,而是将其替换为此版本的 setState 以维护 array 结构。

...
  .then(newItem => this.setState((prevState, props) => ({
        items: [...prevState.items, newItem]
      })
    )
  )

您可能还希望将组件生命周期中的fetch 回调从componentDidMount 挂钩推回componentWillMount 挂钩。

【讨论】:

  • 谢谢它的工作! prevState 之前的三个点是什么
  • Spread Syntax。简而言之,它采用 state.items 的先前值在当前 setState 调用之前的值,并用已经存在的任何内容填充数组,然后添加新的末尾。
  • 感谢您的帮助,在这里肯定学到了一些东西。
  • 乐于助人! :)
  • 我在这方面有点挣扎,而且我们在跨应用程序中创建的样板数量很大,所以我决定创建一个 api 库来处理很多这些问题。看看有没有用:github.com/DigitalGlobe/jetset
猜你喜欢
  • 2018-06-23
  • 2022-01-26
  • 2023-03-21
  • 2021-01-31
  • 2017-12-14
  • 1970-01-01
  • 1970-01-01
  • 2020-09-10
  • 1970-01-01
相关资源
最近更新 更多