【问题标题】:How to access fields of JSON object return by the API?如何访问 API 返回的 JSON 对象的字段?
【发布时间】:2021-10-14 02:47:15
【问题描述】:

我正在尝试显示 API 返回的响应。我能够显示整个 API 响应,但无法显示对象的特定字段。

使用的API是:https://lichess.org/api/user/nihalsarin2004

回复是:

{
  "id": "nihalsarin2004",
  "username": "nihalsarin2004",
  "online": false,
  "perfs": {
    "chess960": {
       "games": 107,
       "rating": 2574,
       "rd": 102,
       "prog": 79
 },
"antichess": {
  "games": 158,
  "rating": 1923,
  "rd": 109,
  "prog": -37
},
"atomic": {
  "games": 4434,
  "rating": 2381,
  "rd": 63,
  "prog": -20
},
"racingKings": {
  "games": 78,
  "rating": 1962,
  "rd": 110,
  "prog": 48,
  "prov": true
},
"ultraBullet": {
  "games": 14270,
  "rating": 2415,
  "rd": 45,
  "prog": -8
},
"blitz": {
  "games": 917,
  "rating": 2912,
  "rd": 68,
  "prog": 35
},
.
.
.
.
"puzzle": {
  "games": 436,
  "rating": 2429,
  "rd": 97,
  "prog": 0
},
"classical": {
  "games": 0,
  "rating": 1500,
  "rd": 500,
  "prog": 0,
  "prov": true
},
"rapid": {
  "games": 0,
  "rating": 1500,
  "rd": 500,
  "prog": 0,
  "prov": true
},
"storm": {
  "runs": 68,
  "score": 109
},
"racer": {
  "runs": 3,
  "score": 129
},
"streak": {
  "runs": 1,
  "score": 4
}
},
"createdAt": 1505668328682,
"profile": {
  "country": "IN",
  "firstName": "Nihal",
  "lastName": "Sarin"
 },
"seenAt": 1628540487222,
"patron": true,
"playTime": {
"total": 2527288,
"tv": 1064938
},
"language": "en-US",
.
.
.
.
"followable": true,
"following": false,
"blocking": false,
"followsYou": false
} 

您也可以在上面给出的链接上查看完整的 API 响应。

我正在从 API 获取数据,尽管我可以通过以下方式访问上述响应的 username

async function lichessProfile(username) {
    await fetch(`https://lichess.org/api/user/${username}`)
    .then((res)=>res.json())
    .then((json) => setData(json));
}

然后像这样访问username

 let username =  JSON.stringify(data.username);

并在我的反应组件中使用它:

<div>
    <br/>
        Name : {username} 
    <br/>
</div>

但如果我想在闪电战中访问评级,我正在使用这个并收到错误:

let blitzRating = JSON.stringify(data.perfs.blitz.rating); 

我在使用上面的行时遇到错误,

虽然我可以在控制台中使用相同的代码进行访问。

有人知道这里有什么问题吗?

【问题讨论】:

  • 使用解析?这很有趣。
  • 数据在通过 API 发送给您之前已被字符串化,只需解析数据,因此它被视为可访问的对象。试试这个,让 ParsedData = JSON.parse(data);然后console.log(ParsedData.perfs.blitz);
  • 也使用问号,这样可以避免在对象不存在时出现错误,如下所示:let blitzRating = JSON.stringify(data?.perfs?.blitz?.rating);
  • 顺便说一下,blitz 不在 perfs 中,所以让 blitzRating = JSON.stringify(data?.blitz?.rating);
  • @blanknamefornow 我正在使用它,但仍然出现错误 let pr = data.perfs;让 blitzData = pr.blitz;让 blitzRating = JSON.stringify(blitzData.rating);我将它用作组件中的 {blitzRating}

标签: javascript node.js reactjs api


【解决方案1】:

您的代码有问题。

  1. 您不必使用stringify 方法。只需let username = data.username;
  2. 您遇到的与 React 组件生命周期相关的问题
  • 因为linchessProfile 组件将在调用从lichessProfile 组件中的API 获取数据的函数之前渲染自己及其所有子组件。
  • lichessProfile 渲染自身时,告诉组件在获取的结果中获取数据,它还没有获取数据,与在undefined 内部获取数据相同。

=> 解决方案:您可以在每次尝试读取获取的数据时编写这样的代码:

let blitzRating = data?.perfs?.blitz?.rating ?? ""; 

注意:您应该阅读React 组件生命周期React Hooks可选链空值合并运算符

【讨论】:

  • 你能澄清一下解决方案代码的实际作用吗?
  • @MohitMaroliyaB17CS036 ?. 被称为 可选链接?? 被称为 Nullish 合并运算符。当代码尝试访问data 属性(如perfs)并且如果data.perfs 等于undefinednull,值空字符串 将分配给blitzRating 变量, 显示时也一样。如果dataempty 对象,(data = {}),所以data.perfs 等于undefined,那么data.perfs.blitz 将在这个问题中引发同样的错误。将?. 添加到data?.perfs?.blitz 将自动将undefined 值分配给变量,而不是引发错误。
【解决方案2】:

请告诉我们您何时使用let blitzRating = JSON.stringify(data.perfs.blitz.rating);。我认为您在处理数据之前使用它。

请注意,您不必使用stringify 方法。就let blitzRating = data.perfs.blitz.rating;

【讨论】:

  • 我在 React 组件中使用它在 name 之后。像闪电战评级一样:{blitzRating}
  • 如果还没有任何数据,有 3 种方法可以不渲染组件。 {data &amp;&amp; &lt;Component data={data} /&gt;} 在渲染前检查 if(!data) { return null }。此方法将阻止所有组件渲染,直到没有任何数据。在 JSX 中使用一些 &lt;Loading /&gt; 组件和 ternar 运算符。在这种情况下,您将能够渲染不需要数据的组件的所有其他部分 -> {data ? &lt;Component data={data} /&gt; : &lt;Loading&gt;}
  • 检查这里:https://codepen.io/
猜你喜欢
  • 1970-01-01
  • 2023-01-09
  • 1970-01-01
  • 1970-01-01
  • 2017-11-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-18
  • 1970-01-01
相关资源
最近更新 更多