【问题标题】:Access nested JSON data in ReactJS when clicking Search?单击搜索时访问 ReactJS 中的嵌套 JSON 数据?
【发布时间】:2020-07-10 03:02:11
【问题描述】:

我已经尝试了其他几种方法来执行此操作,例如

How to read a nested JSON in React?

Can't access nested JSON Objects in React

当我点击“搜索”时,我正在尝试查询 API。目前,当我单击“搜索”时,API 会查询正确的 URL,但我无法访问返回的数据。发回的数据如下所示:

{
  "option_activity": [
    {
      "id": "5f033b253c8cf100018a312f",
      "bid": "0.6",
      "ask": "1.0",
      "midpoint": "0.8",
      "updated": 1594047269
    },
    {
      "id": "5f033b253c8cf100018a312f",
      "bid": "0.6",
      "ask": "1.0",
      "midpoint": "0.8",
      "updated": 1594047269
    },

有数百个这样的项目。它在控制台中的样子:

我在做什么来查询 api:

  fetchData() {
        var val = this.state.searchedValue;
        var url = "URL/TO/API"
        fetch(url)
    .then(res => res.json())
    .then((res) => {
            const itemsList = res.option_activity;

            this.setState({
                items: itemsList
            },
            function () {
                console.log(itemsList);
            }
            );
            // console.log(this.state.items)
            
        },
        
        // Note: it's important to handle errors here
        // instead of a catch() block so that we don't swallow
        // exceptions from actual bugs in components.
        (error) => {
        
             console.log(error);

        },
        // console.log(this.state.items)
    )
}

当网络记录来自 API 的响应时,控制台日志只为 this.state.items 记录一个空数组“[]”,该数组被初始化为一个空数组。如何将“option_activity”的内容保存到数组“items”中,通过该数组访问id、bid、ask、midpoint等?

因此,items[0] 可以访问 items[0].id、items[0].midpoint 等。

提前致谢

解决方案在正确标记答案的 cmets 中

【问题讨论】:

  • 这看起来应该可以工作,并为每个元素提供一个 id 数组,因此似乎没有足够的代码来重现问题。如果您想要完整的结构,请删除 map 调用。你有任何错误吗?唯一的console.log 位于错误处理程序中,因此如果它确实触发,那将是空的。
  • @Santoshi24 ,setState 方法是异步操作,console.log 将只打印一个空数组,因为那是初始状态。,您可以使用回调来查看状态是否正在更新
  • @Satoshi24 您的console.log 发生在错误函数中,您确定在将这些项目设置为状态之前没有发生错误吗?
  • @HarmandeepSinghKalsi 使用回调会产生相同的空数组。
  • @RyanWilson 出现登录错误。删除它并通过回调记录仍然会产生一个空数组

标签: javascript reactjs


【解决方案1】:

您是在访问不同域的 API URL 吗?如果是这样,您很可能实际上遇到了 CORS 错误。如果您尝试以编程方式访问另一个域上的端点,浏览器将检查特定标头以确保 API 允许您这样做。如果它没有看到这些标题,它将引发错误(您应该在控制台中看到)。网络选项卡仍会显示预期的有效负载,但您无法在 Javascript 中访问它。

现在,您只是在出现错误时登录控制台。因此,如果您在网络选项卡中看到响应,但总是在错误处理程序中结束,则表明响应有问题(CORS,或者以某种方式返回的格式错误的数据可能无法解析为 JSON )。

您还应该注意,您当前的日志并不是特别有用。您只会打印出 items 的旧值。由于您显然从未设置过它(请注意,您在错误处理程序中),因此您希望该值与尝试设置 items 的值之前的值相同(可能是初始空数组)。

【讨论】:

  • 了解 CORS 错误很有趣 - 我在控制台中没有看到相关的 CORS 错误。我从错误中删除了控制台的日志记录(错误地将其放在那里),但仍然无法记录除空数组之外的项目数组
  • 您能否更新您的问题以将控制台包含在正确的位置?如果它到达then 子句,请重新阅读我的第 3 段。如果你仍然只是在做一个console.log(items),它不会像你期望的那样工作。您可能希望在渲染函数中实际执行console.log(this.state.items),或在您的then 子句中执行console.log(itemsList)
  • 哈哈。我认为错误比我意识到的要简单。这就是我现在得到的: SyntaxError: Unexpected token
  • 哈哈,是的,当你的 api 服务器出现某种错误时,通常会发生这种情况,它实际上返回的是 HTML 而不是 JSON。
  • 啊。这是有道理的,在文档中,他们在最后使用带有 -H "accept: application/json" 的 curl 查询。知道如何将其合并到我的查询中吗?
【解决方案2】:

首先,如果要访问id、bid等,不需要使用map转换返回的活动列表。

                const itemsList = res.option_activity;

                this.setState({
                    items: itemsList
                });

其次,如果要在使用setState后立即读取状态,则需要使用回调,类似于以下代码sn-p。

this.setState({ boardAddModalShow: true }, function () {
    console.log(this.state.boardAddModalShow);
  });

这是因为根据React docs

setState() 不会立即改变 this.state 而是创建一个 等待状态转换。调用 this 后访问 this.state 方法可能会返回现有值。没有 保证对 setState 的调用和调用的同步操作可能 进行批处理以获得性能提升。

【讨论】:

  • 删除映射不起作用,我添加了一个回调来打印项目,但它再次记录了一个空数组。
  • 没关系。它确实有效,我没有意识到我收到的是 HTML 而不是 JSON。
猜你喜欢
  • 1970-01-01
  • 2016-07-23
  • 2020-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-02
  • 1970-01-01
相关资源
最近更新 更多