使用 ReactJS 和 fetch-api 访问和显示 JSON 时遇到问题

Posted

技术标签:

【中文标题】使用 ReactJS 和 fetch-api 访问和显示 JSON 时遇到问题【英文标题】:Trouble accessing and displaying JSON using ReactJS and the fetch-api 【发布时间】:2020-03-29 16:47:47 【问题描述】:

感谢大家的帮助!

我查看了几个类似的问题,但无法推断他们的答案来解决我的问题。

我正在使用 ReactJS 应用程序来使用来自网站的 JSON。我正在使用来自https://pusher.com/tutorials/consume-restful-api-react 的代码并对其进行更改以适应我的情况。

目前,当我查看 index.js 时,我收到错误“TypeError: assetList.assets 未定义。”鉴于下面的 JSON 和代码,我需要更改为 显示资产及其属性的列表?

我希望显示器看起来像下面的所需显示器。

所需的显示。

There are two 2 assets:<br/>
  id: 1317 Filename: PROCESS_FLOW.pdf  
  id: 1836 Filename: 004527_FS.jpg

从网站使用的 JSON

"totalNumberOfAssets":2,
"assets":[
  "id":"1317","attributes":"Filename":["PROCESS_FLOW.pdf"],
  "id":"1836","attributes":"Filename":["004527_FS.jpg"]
]

components/assetList.js

import React from 'react'

const AssetList = (assetList) => 
  return (
    <div>
      There are assetList.totalNumberOfAssets assets:
      assetList.assets.map((asset) => (
      <div>
        id: asset.id  filename: asset.filename
      </div>
      ))
    </div>
  )
;

export default AssetList

App.js

import React, Component from 'react';
import AssetList from './components/assetList';

class App extends Component 
    render() 
        return (
            <AssetList assetList=this.state.assetList />
        )
    

    state = 
        assetList: []
    ;

    componentDidMount() 
        fetch('http://ligitaddress/api/v1/asset')
            .then(res => res.json())
            .then((data) => 
                this.setState( assetList: data )
            )
            .catch(console.log)
    


export default App;

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

ReactDOM.render(<App />, document.getElementById('root'));

【问题讨论】:

this.state.assetList 的初始值是多少?您可能必须首先将其设置为空值。我的猜测是它试图在从 fetch 返回assetList 数据之前执行assetList.assets.map 【参考方案1】:

发生这种情况是因为您的 components/assetList.js 试图在未定义的情况下访问assetList.assets.map 上的assetList.assets。

当API请求发出但尚未返回时,assetList上的资产尚未定义,因为App.js上的assetList被初始化为一个空数组。

您可以将 components/assetList.js 上的行替换为 assetList.assets &amp;&amp; assetList.assets.map(...) 并且应该这样做

【讨论】:

【参考方案2】:

在您的第一次渲染中,this.state.assetList 的值是一个数组:

state = 
    assetList: []
;

但是你将它传递给&lt;AssetList&gt;

const AssetList = (assetList) => 
  return (
    <div>
      There are assetList.totalNumberOfAssets assets:
      assetList.assets.map((asset) => (
      <div>
        id: asset.id  filename: asset.filename
      </div>
      ))
    </div>
  )
;

assetList.assets.map 的行试图在未定义的事物上调用 map()。 (您可以访问数组上的属性assets,它将是undefined)似乎它期望assetList 是一个包含assets 数组的对象,但在您的父组件中assetList 是初始化为一个数组...简而言之,您对您希望在哪里存储什么样的数据感到困惑。

要么改变你的初始状态,以反映你期望它如何传递到&lt;AssetList&gt;

state = 
    assetList: 
        assets: []
    
;

和/或更改您的 &lt;AssetList&gt; 组件以正确检查其属性:

const AssetList = (assetList) => 
  return (
    <div>
      There are assetList.totalNumberOfAssets assets:
      Array.isArray(assetList.assets) && assetList.assets.map((asset) => (
      <div>
        id: asset.id  filename: asset.filename
      </div>
      ))
    </div>
  )
;

【讨论】:

太棒了!谢谢你。我将状态更改为assetList:assets:[]。然后用asset.id访问id,用asset.attributes.Filename访问文件名。 @jddsm 乐于助人。请将其中一个答案标记为已接受,以表明问题已得到解决。

以上是关于使用 ReactJS 和 fetch-api 访问和显示 JSON 时遇到问题的主要内容,如果未能解决你的问题,请参考以下文章

ReactJS:如何使用动态键访问和更新嵌套状态对象?

每次有人使用 firebase 和 Reactjs 访问页面时计算浏览量

Reactjs - 处理程序路由器访问

Apollo GraphQl 模型属性未访问 ReactJs 中的对象

阻止用户访问其他路由 - ReactJS - React-Router -

使用 reactjs 从 rest api 访问数据