React - 从 API 获取数据并映射嵌套的 JSON
Posted
技术标签:
【中文标题】React - 从 API 获取数据并映射嵌套的 JSON【英文标题】:React - Fetch Data from API and map nested JSON 【发布时间】:2022-01-18 05:58:51 【问题描述】:几天来,我正在尝试解决以下问题。当然,我已经研究并尝试了几种错误消息的解决方案,不幸的是它们都不起作用。我不知道我做错了什么,因此想问问你。 :)
错误消息: “TypeError:无法读取未定义的属性(正在读取'map')”
代码:
function App()
const [games, setGames] = useState();
useEffect(() =>
getGames();
async function getGames()
const response = await fetch(
"https://v3.football.api-sports.io/fixtures?season=2021&league=78&date=2021-12-04",
method: "GET",
headers:
"x-rapidapi-host": "v3.football.api-sports.io",
"x-apisports-key": "XXX",
,
);
const data = await response.json();
setGames(data.parameters);
, []);
return (
<div>
<h1>Games</h1>
<div className="games">
games.map((game, index) => (
<div key=index>
<h2>game.season</h2>
</div>
))
</div>
)
</div>
);
export default App;
JSON: JSON GET EXAMPLE 稍后我想从 JSON 文件中提取团队。例如:response.teams.home.name
提前感谢您的关注! :) 如果有任何信息缺失,请告诉我。
问候和感谢
【问题讨论】:
首先,不要公开分享您的私有 API 密钥。你的初始状态是空的,你可以创建一个类似 games && games.map(xxx) 的条件。 我看到“参数”属性是一个对象,所以你不能在那里使用地图功能。如果你执行 setGames(data.response) 那么你可以使用 map 函数将你的状态变成一个列表。 为什么不升级到 React 17+ 并利用函数组件?您已经在使用useState
挂钩。
现在已经在上述条件下尝试过了,不幸的是它也没有工作。但取而代之的是一条新的错误信息:TypeError: games.map is not a function 还删除了“参数”并使用 setGames(data.response) 进行了尝试。也没有成功。
见下面的my response。你可以直接运行sn -p。只要您提供 API 密钥。
【参考方案1】:
如果您想适当地映射它,您需要了解数据的结构。
注意:不要将数组索引用于映射中项目的key
。每个游戏都包含一个fixture
对象和一个id
。
const API_KEY = prompt('Supply the API key'); // Provide the key first!
const useEffect, useState = React;
const apiHost = 'v3.football.api-sports.io';
const apiUrl = `https://$apiHost/fixtures`;
const apiKey = API_KEY;
const toParamString = (obj) => new URLSearchParams(obj).toString();
const getGames = ( season, league, date ) =>
const url = `$apiUrl?$toParamString( season, league, date )`;
return fetch(url,
method: 'GET',
headers:
'x-rapidapi-host': 'v3.football.api-sports.io',
'x-apisports-key': apiKey,
,
)
.then(response => response.json())
.then(data => data.response);
;
const Score = (props) =>
const game: fixture: date , score: fulltime , teams = props;
return (
<div className="score">
<div className="score-date">new Date(date).toLocaleString()</div>
<div className="score-grid">
<div>teams.home.name</div>
<div>teams.away.name</div>
<div>fulltime.home</div>
<div>fulltime.away</div>
</div>
</div>
);
;
const App = () =>
const [games, setGames] = useState([]);
useEffect(() =>
getGames(
season: 2021,
league: 78,
date: '2021-12-04'
).then(data => setGames(data));
, []);
return (
<div>
<h1 style= textAlign: 'center' >Games</h1>
<div className="games">
games.map((game) =>
const fixture: id = game;
return (
<Score key=id game=game />
);
)
</div>
</div>
);
;
ReactDOM.render(<App />, document.getElementById('react-app'));
html, body
width: 100%;
height: 100%;
margin: 0;
padding: 0;
body
display: flex;
flex: 1;
#react-app
display: flex;
flex-direction: column;
align-items: center;
flex: 1;
.score
border: thin solid grey;
margin: 0.667em;
padding: 0.33em;
.score-date
display: flex;
justify-content: center;
font-weight: bold;
font-size: larger;
margin-bottom: 0.25em;
.score-grid
display: grid;
grid-template-columns: repeat(2, 1fr);
.score-grid div
display: flex;
justify-content: center;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react-app"></div>
【讨论】:
有效! :) 非常感谢您将如此详细的代码放到网上!这非常有帮助!现在将研究代码以了解它是如何工作的。【参考方案2】:你可以试试这个吗?
function App()
const [games, setGames] = useState();
useEffect(() =>
getGames();
async function getGames()
const response = await fetch(
"https://v3.football.api-sports.io/fixtures?season=2021&league=78&date=2021-12-04",
method: "GET",
headers:
"x-rapidapi-host": "v3.football.api-sports.io",
"x-apisports-key": "3914b827d25c9a793d6af1ec9c312d55",
,
);
const data = await response.json();
setGames(data.parameters);
, []);
return (
<div>
<h1>Games</h1>
<div className="games">
Object.keys(games).length > 0 && games.map((game, index) => (
<div key=index>
<h2>game.season</h2>
</div>
))
</div>
)
</div>
);
export default App;
【讨论】:
'parameters' 键是一个对象,因此您无法通过它进行映射。请添加更多信息来解释您所做的修复。 很遗憾,您的想法也没有奏效:/ 现在出现错误消息:TypeError: games.map is not a function 我一直没有进行任何重大更改。总是尝试并失败 :D 例如,已经尝试一步一步地映射“游戏”以越来越深入。但是,总是出现错误消息。然后我在没有 .map() 的情况下尝试了它并收到以下错误消息:错误:对象作为 React 子项无效(找到:带有键 的对象)。如果您打算渲染一组子项,请改用数组。由此我再次明白我必须通过 .map() 映射“游戏”。从那以后,我一直在兜圈子,找不到更多的解决方案。以上是关于React - 从 API 获取数据并映射嵌套的 JSON的主要内容,如果未能解决你的问题,请参考以下文章
如何在 React 的 API 中渲染嵌套在对象中的数组中的数据?