猿问

无法在反应中访问获取响应中的深层嵌套对象

因此,我在 Stack 和 Web 上偶然发现了很多示例,其中从异步获取调用访问深层嵌套对象返回未定义。许多答案都解决了其他文章,从而导致了对象和数组的访问方式。其他人声称这是异步操作的原因。但我实在无法理解它。


这是数据:


base: "stations"

clouds: {all: 1}

cod: 200

coord: {lon: -81.38, lat: 28.54}

dt: 1607561322

id: 4167147

main: {temp: 51.28, feels_like: 45.97, temp_min: 48.99, temp_max: 53.6, pressure: 1021, …}

name: "Orlando"

sys: {type: 1, id: 5234, country: "US", sunrise: 1607515628, sunset: 1607552963}

timezone: -18000

visibility: 10000

weather: [{…}]

wind: {speed: 4.52, deg: 271}

这是代码,注意 useEffect 回调中的 setWeatherData


function WeatherDisplay(props){

  const [weatherData, setWeatherData] = useState({})


  useEffect(() => {

    fetch(`http://api.openweathermap.org/data/2.5/weather?q=Orlando&units=imperial&appid=3abd9c2df6a249e8abcf4f812de0a627`)

    .then(res => res.json())

    .then(data => {

      setWeatherData({

        data,

        name: data.name,

        main: data.main,

        ...data.main

      })

    })

    .catch(err => console.log(err))

  }, [])



  return(

    <>

      <Media style={{backgroundColor: "gray", borderRadius: "5px", height: "5.5rem"}}>

        <IconContext.Provider value={{size: "5rem", style:{fontWeight: "200"}, className:"align-self-center"}}>

          <TiWeatherPartlySunny />

        </IconContext.Provider>

          {console.log(weatherData)}

          {console.log(weatherData.name)}

          {console.log(weatherData.main)}

          {console.log(weatherData.temp)}

      </Media>

    </>

  )

}

https://i.stack.imgur.com/8aEj7.png

这就是首先开始的方式,我只是将WeatherData设置为数据,因为我可以渲染weatherData.name(奥兰多),但由于某种原因weatherData.main.temp返回错误,因为weatherData.main导致未定义。我四处询问,他们说这是因为承诺并且它是异步的,所以我必须使用条件等等,但这仍然不能解释它如何能够访问weatherData.name。与weatherData.clouds和.sys相同

我继续传播我想要的对象的值,但我可以想到我的解决方法没有用的简单情况。

我想知道这是否是反应保存深度嵌套对象的值的方式,但我真的不知道。


米脂
浏览 122回答 3
3回答

UYOU

是的,这是因为异步行为。该weatherData对象将始终存在(最初作为 {},然后在请求完成后使用获取的数据)。在初始渲染中,weatherData.namewill equal{}.name将返回 undefined,但不会导致错误。但是,当您运行时,weatherData.main.temp它将 equal&nbsp;{}.main.temp,这意味着您实际上正在调用undefined.temp这将引发错误。仅当mainprop 未定义时才会抛出此错误,这意味着一旦实际获取数据,它就应该正常工作。您可以通过几种不同的方法来解决这个问题,我推荐以下两种方法之一:如果提取尚未完成,则呈现“正在加载数据...”等的条件渲染。条件访问器。尝试访问weatherData.main?.temp而不是weatherData.main.temp.&nbsp;不确定它是否能在 JSX 内部工作,但假设您使用的是最新版本的 babel ,它可以正确转换条件分支,那么它应该可以在外部工作。您还可以创建一个weatherData定义了预期接口的初始对象,但所有值都设置为undefined.换句话说,const initialWeatherData = {&nbsp; name: undefined,&nbsp; main: {&nbsp; &nbsp; temp: undefined,&nbsp; }}// etc, leaving out most of the object as I'm sure you get what I'm trying to do// just make sure you define the entire interfaceconst [weatherData, setWeatherData] = useState(initalWeatherData);

三国纷争

如果你设置如下setWeatherData({&nbsp; &nbsp; data})您的天气数据将是{&nbsp; &nbsp; data: {&nbsp; &nbsp; &nbsp; &nbsp; main: {...},&nbsp; &nbsp; &nbsp; &nbsp; name: '...'&nbsp; &nbsp; &nbsp; &nbsp; sys: {...}&nbsp; &nbsp; }}要访问 main,您应该使用weatherData.data.main

慕工程0101907

您可以通过此代码和 API 图像来理解这个想法。希望对您有帮助import React&nbsp; from 'react'class GetData extends React.Component {&nbsp; &nbsp; state = {&nbsp; &nbsp; &nbsp; &nbsp; data: []&nbsp; &nbsp; };&nbsp; &nbsp; async componentDidMount() {&nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const url = "http://localhost:8000/blogList";&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const response = await fetch(url);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const data = await response.json();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log(data);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.setState({ data: data.result });&nbsp; &nbsp; &nbsp; &nbsp; } catch (err) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log(err);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; render() {&nbsp; &nbsp; &nbsp; &nbsp; const { data } = this.state&nbsp; &nbsp; &nbsp; &nbsp; return (&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <div>{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <ul>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {data.map((item, i) => {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return <li key={item.id}>{item.title}</li>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; })}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </ul>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </div>&nbsp; &nbsp; &nbsp; &nbsp; );&nbsp; &nbsp; }}export default GetData
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答