【问题标题】:Cant use dot or bracket notation to access keys or data in json/javascript object saved to state after fetch无法使用点或括号表示法访问 json/javascript 对象中的键或数据,在获取后保存到状态
【发布时间】:2019-12-17 03:24:43
【问题描述】:

我目前正在学习 react-native 一段时间后,我遇到了一个我不明白的奇怪事件。

我正在从 API 获取 JSON 文件并将其保存在我的状态中。当我尝试使用点和括号表示法访问值时,文件中的其他地方会破坏我的代码“未定义不是对象”,并且该常量的值确实未定义。但奇怪的是,如果我在我的 fetch 和点/括号符号中使用 setState 来获得一个特定的值,它就可以正常工作。但我想拥有这个功能,而我将通过数据进行很多映射。

我读到我可能需要使用 JSON.parse,但可以确定在我的 fetch 中放置它的位置,它在 console.log 中返回了一个错误。

JSON.stringify 有效,但我只有一个巨大的字符串,所以失去了对象的力量。

点和括号表示法尝试了这一切,正如我所说的在 fetch 中完美工作,但是在调用状态时

先将 state 设置为 const,然后将其传递到 console.log,没有区别。

fetchWeather(lat = 15, lon = 85) {
    fetch(
      `http://api.openweathermap.org/data/2.5/forecast?lat=${lat}&lon=${lon}&APPID&APPID=${API_KEY}&units=metric`,
    )
      .then(res => res.json())
      .then(json => {
        this.setState({
          forecast: json.list,
          temp: json.list[0].main.temp // WORKS! returns temp eg 25.34
          isLoading: false,
        });
      })
      .catch(error => console.log(error));
}
console.log(this.state.forecast[0]); //works I get the first index of an array of objects but has and added key Object {}
console.log(this.state.forecast[0].main.temp); //undefined
console.log(this.state.forecast[0]['main']['temp']); //undefined

我看到这个 Object {} 出现在控制台中,但也许这没什么好担心的?

例如。

"main": Object {
    "grnd_level": 1008.34,
    "humidity": 54,
    "pressure": 1013.04,
    "sea_level": 1013.04,
    "temp": 28.1,
    "temp_kf": 4.74,
    "temp_max": 28.1,
    "temp_min": 23.36,
},

应该是,

"main": {
    "grnd_level": 1008.34,
    "humidity": 54,
    "pressure": 1013.04,
    "sea_level": 1013.04,
    "temp": 28.1,
    "temp_kf": 4.74,
    "temp_max": 28.1,
    "temp_min": 23.36,
  },

我希望 console.log(this.state.forecast[0].main.temp) 返回 23.45console.log(this.state.forecast[0]['main'])return

"grnd_level": 1008.34,
"humidity": 54,
"pressure": 1013.04,
"sea_level": 1013.04,
"temp": 28.1,
"temp_kf": 4.74,
"temp_max": 28.1,
"temp_min": 23.36,

https://samples.openweathermap.org/data/2.5/forecast?lat=35&lon=139&appid=b6907d289e10d714a6e88b30761fae22

https://openweathermap.org/forecast5

【问题讨论】:

  • 从您的问题和要点来看,我并不清楚您在哪里尝试访问您的状态并遇到错误 - 但是,请注意 setState enqueues 变化。不要尝试在调用setState 后立即访问这些字段。 setState 接受回调作为您可以使用的第二个参数。
  • 将对象存储在我的状态中作为预测是很奇怪的,然后当我在我的渲染方法中放置一个 console.log 时,无法使用点或括号表示法访问键和值。好像它不是一个对象?您将如何从对象访问“temp”?
  • 请注意,此条件的计算结果始终为 true,并且即使在状态被正确填充之前,console.log 也会被尝试:if (this.state.forecast !== {}) { - 如果它在此 console.log 中中断,那么这是原因。
  • 我已将此作为答案添加,如果我的假设正确,请接受。

标签: javascript json reactjs fetch native


【解决方案1】:

我假设您的 Gist 中的这部分导致了错误:

if (this.state.forecast !== {}) {
  console.log(this.state.forecast[0].main);
}

你正在用一个空对象 {} 初始化你的 state.forecast 并尝试检查它。

从数据结构的角度来看,这有点误导,因为实际的内容会是一个数组。

更重要的是,不过,这两个变量是通过身份进行比较的,并且正确的操作数是每次调用 render 时在堆栈上新创建的一个空对象,并且永远不会等于 forecast 中的任何内容。因此,条件总是评估为true,这会导致尝试访问在第一次渲染时还不存在的数据。

由于您只等待通过fetch 调用填充forecast,并且已知forecast 的内容,因此使用state 初始化state 应该足够了forecast: null(或不根本)然后检查是否设置了forecast(不是false,不是null,不是undefined,不是0,不是'',...):

if (this.state.forecast) {
  console.log(this.state.forecast[0].main);
}

或者更严格一点:

if (typeof this.state.forecast === 'object') { // typeof array is also 'object'
  console.log(this.state.forecast[0].main);
}

【讨论】:

  • 它必须与生命周期或范围有关,因为它在设置状态内工作,而不是在我假设的应用程序的其他地方?
  • “对象:{”只是您的浏览器转储变量的方式 - Firefox 会这样做,Chrome 不会。
  • App.js Gist 中的哪一行失败了?
  • 我的错误信息说 - TypeError: undefined is not an object (evalating 'this.state.forecast[0].main')
  • 啊,对不起,我错过了您使用空对象 {} 初始化状态 - 删除它,初始化为 null 或根本不初始化,它会起作用。我会相应地修改我的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-31
  • 2019-10-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多