TypeError:无法读取 JSONPlaceholder 未定义的属性“url”
Posted
技术标签:
【中文标题】TypeError:无法读取 JSONPlaceholder 未定义的属性“url”【英文标题】:TypeError: Cannot read property 'url' of undefined for JSONPlaceholder 【发布时间】:2020-07-24 19:18:36 【问题描述】:我正在尝试从 jsonPlaceholder 加载图片。当我控制台注销图像数组时,它可以成功运行。当我尝试从元素调用 URL 时,它会引发 TypeError。我试着用异步的方式来做,即使这样也行不通。有什么解决方法吗?可能是什么问题?
import React, Component from 'react';
import axios from 'axios';
class Home extends Component
state =
posts : [],
images : []
;
componentDidMount = async () =>
const res = await axios.get('https://jsonplaceholder.typicode.com/posts');
this.setState(posts: res.data.slice(0,10))
const res2 = await axios.get('https://jsonplaceholder.typicode.com/photos');
this.setState(images: res2.data.slice(0,10))
render = () =>
const posts = this.state.posts;
const images = this.state.images;
const PostList = this.state.posts.length ? (
this.state.posts.map((post,index) =>
return(
<div className = "post card" key = post.id>
<div className = "card-content">
<div className = "card-title">
post.title
</div>
<div className>
(this.state.images[index].url) //console.log(this.state.images[index] works, but .URL doesn't
</div>
<div>
<p>post.body</p>
</div>
</div>
</div>
)
)) : (<div className = "center">No Posts!</div> )
return(
<div className = "container">
<div className = "center">
PostList
</div>
</div>)
export default Home;
【问题讨论】:
它是 thumbnailUrl,而不是 url 如果您是数组映射中的 console.log(this.state.images[index]),您每次都会得到什么 【参考方案1】:问题存在于多个setState
。一旦你设置了状态,它就会更新并呈现asynchronously
。所以没有等待next
setState。最好在一次调用中设置两个数据。
componentDidMount = async () =>
const res = await axios.get('https://jsonplaceholder.typicode.com/posts');
this.setState(posts: res.data.slice(0,10))
const res2 = await axios.get('https://jsonplaceholder.typicode.com/photos');
this.setState(images: res2.data.slice(0,10))
您可以像这样清理代码:
工作岗位: https://codesandbox.io/s/articlepodcast-wd2rv?file=/home.js:0-1214
import React, Component from "react";
import axios from "axios";
class Home extends Component
constructor(props)
super(props);
this.state =
posts: [],
images: []
;
componentDidMount = async () =>
const res = await axios.get("https://jsonplaceholder.typicode.com/posts");
const res2 = await axios.get("https://jsonplaceholder.typicode.com/photos");
this.setState(
posts: res.data.slice(0, 10),
images: res2.data.slice(0, 10)
);
;
render = () =>
const posts, images = this.state;
const PostList = posts.length ? (
posts.map((post, index) =>
return (
<div className="post card" key=post.id>
<div className="card-content">
<div className="card-title">post.title</div>
<div className>images[index].url </div>
<div>
<p>post.body</p>
</div>
</div>
</div>
);
)
) : (
<div className="center">No Posts!</div>
);
return (
<div className="container">
<div className="center">PostList</div>
</div>
);
;
export default Home;
【讨论】:
【参考方案2】:由于您的第一个 setState
,它会在第二个异步等待之前进行渲染。
const res = await axios.get('https://jsonplaceholder.typicode.com/posts');
const res2 = await axios.get('https://jsonplaceholder.typicode.com/photos');
this.setState(images: res2.data.slice(0,10), posts: res.data.slice(0,10))
像这样试试。
最好有这样的东西;
this.setState(
posts: res.data.slice(0,10).map((post, index) => (
...post,
image: res2.data.slice(0,10)[index]
))
)
【讨论】:
【参考方案3】:问题
由于componentDidMount
函数中设置状态的方式而发生错误。为了分解为什么会发生这种情况,我将解释代码试图做什么:
首先,Axios 将发送一个 get 请求 来获取帖子,因为这是一个正在等待的异步操作,当获取数据时,javascript 将处理其他事情。因此它将继续并第一次运行render
函数。渲染函数将返回No Posts!
,因为this.state.posts.length ?
是false
。
然后当我们完成获取帖子时,componentDidMount
将继续,在这种情况下,它将更新状态 this.setState(posts: res.data.slice(0,10))
,每次调用 setState
时,它都会告诉 react 为该组件运行 render
函数再次确保页面反映了我们的状态。然后我们进入下一行等待获取照片,而我们正在等待render
函数将第二次运行,因为(正如刚才所说)我们改变了组件的状态。在这个时间点,我们仍然没有照片,因为我们正在等待它们,但是我们确实有帖子,所以检查我们是否有帖子 this.state.posts.length ?
将是 true
。然后当我们到达images[index]
时,它将是未定义的,因为我们还没有完成获取照片并将它们设置为状态。 (我希望这可以帮助您理解问题)。
解决方案
在我们获得所有数据后更新状态,以便render
函数第二次运行我们有图像:
const res = await axios.get("https://jsonplaceholder.typicode.com/posts");
const res2 = await axios.get("https://jsonplaceholder.typicode.com/photos");
this.setState(
posts: res.data.slice(0, 10),
images: res2.data.slice(0, 10)
);
我还建议向this.state.images
添加安全检查,就像您对帖子所做的那样,以确保您在尝试使用之前确实拥有数据。对于来自网络调用的所有数据,这是一个很好的做法,因为在尝试从服务获取数据时可能会发生许多意想不到的事情。
最后,我还建议您尝试使用 chrome 调试器跟踪您的代码。这将帮助您了解代码正在做什么,以便更好地理解为什么会发生这样的问题。这是一个很好的指南,说明如何做到这一点。 https://developers.google.com/web/tools/chrome-devtools/javascript
【讨论】:
以上是关于TypeError:无法读取 JSONPlaceholder 未定义的属性“url”的主要内容,如果未能解决你的问题,请参考以下文章