[英]I can not get data from this.state
我从我的后端收到 JSON,我将它保存在我的状态中,我想在另一个 React 组件的 props 中使用它,但它不起作用。
我尝试在我的组件的道具中显示需要日期 - {this.state.movies["0"]["title"]}
,但它不起作用。
constructor() {
super();
this.state = {
movies: []
}
}
componentDidMount() {
this.getAllMoviesForMainPage();
}
getAllMoviesForMainPage() {
axios.get("http://localhost:8080/showAll")
.then(response => {
this.setState({ movies: response.data })
})
}
render() {
return (
<div className="qwerty">
<MainPageComponent />
<div className='moviePreviewGrid'>
<Router>
<div className="moviePreviewGrid-row">
<div className="moviePreviewGrid-col">
<MoviePreview
Title={this.state.movies["2"]["title"]}
MoviePreviewAvatar={DrivePoster}
SeeMore="unrelated long string here"
/>
<NavLink to="/showByTitle/Драйв">
<button type="button" className="myBtn">See more</button>
</NavLink>
</div>
和我的 JSON 的结构
[
{
"id": 1,
"title": "Джокер",
"releaseDate": "2019",
"genre": "Триллер, драма, криминал",
"duration": "122 минуты",
"rating": 8.7,
"criticReviews": [
{
"criticName": "Anton",
"review": "anton review"
},
{
"criticName": "OldCritic",
"review": "old review"
}
],
"userReviews": [
{
"nickName": "Igor",
"review": "igor review"
},
{
"nickName": "Nik",
"review": "nik review"
}
]
},
{
"id": 2,
"title": "Ирландец",
"releaseDate": "2019",
"genre": "Драма, триллер, криминал, биографический",
"duration": "209 минут",
"rating": 8.4,
"criticReviews": [
{
"criticName": "YoungCritic",
"review": "young review"
}
],
"userReviews": [
{
"nickName": "Gambit",
"review": "gambit review"
},
{
"nickName": "Andrew",
"review": "andrew review"
}
]
},
{
"id": 3,
"title": "Драйв",
"releaseDate": "2011",
"genre": "Боевик, драма",
"duration": "100 минут",
"rating": 7.8,
"criticReviews": [
{
"criticName": "Critic",
"review": "review"
}
],
"userReviews": [
{
"nickName": "Anton",
"review": "anton review"
}
]
},
{
"id": 4,
"title": "Последний человек на Земле",
"releaseDate": "2015",
"genre": "Комедия",
"duration": "22 минуты",
"rating": 7.3,
"criticReviews": [
{
"criticName": "NewCritic",
"review": "new review"
}
],
"userReviews": [
{
"nickName": "Atomf7",
"review": "atomf7 review"
}
]
},
{
"id": 5,
"title": "Интерстеллар",
"releaseDate": "2014",
"genre": "Фантастика, драма, приключения",
"duration": "169 минут",
"rating": 8.6,
"criticReviews": [
{
"criticName": "Nik",
"review": "nik review"
}
],
"userReviews": [
{
"nickName": "Alice",
"review": "alice review"
}
]
}
]
我不会有例如第一部电影的标题
在第一个初始化中, this.state.movies
的长度为 0 所以this.state.movies["2"]["title"]
当然根本没有价值,因为getAllMoviesForMainPage
是异步的(axios 调用)并且需要完成的时间有点长,所以首先你必须给它一个初始值,只有当请求完成时你才能给它真正的值。
例子:
<MoviePreview
Title={this.state.movies.length > 0 ? this.state.movies[2].title : ""}
MoviePreviewAvatar={DrivePoster}
/>
通常一个状态, isLoading
用于这种情况。 这样您就可以知道何时收到您的数据。
您正在componentDidMount
中发出 GET 请求,该请求是async
因此直到承诺在.then(..
您的状态不包含movies
response.data
。
要记住的重要一点是,每次执行this.setState(..
,因此在getAllMoviesForMainPage
方法中执行 setState 之前,组件都会重新渲染,初始渲染将发生,并且它将在this.state.movies
包含一个空数组你在构造函数中定义的
此外,由于您的响应包含对象数组,您将使用movies['2'].title
而不是movies['2']['title']
所以你的渲染方法应该包含这样的东西来显示电影预览:
<div className="moviePreviewGrid-col">
{this.state.movies.length ? (
<MoviePreview
Title={this.state.movies['2'].title}
MoviePreviewAvatar={DrivePoster}
SeeMore="unrelated long string here"
/>
) : (
<PlaceHolderPreview />
)}
<NavLink to="/showByTitle/Драйв">
<button type="button" className="myBtn">
See more
</button>
</NavLink>
</div>
PlaceHolderPreview
可以是您将显示的另一个组件——以及用于预览的占位符。
希望这一切都有意义。
在第一次渲染中,电影尚未从 api 中获取。
所以你需要有条件地渲染它。
import React, { Component } from "react";
import axios from "axios";
export default class Test extends Component {
constructor() {
super();
this.state = {
movies: [],
loading: true
}
}
componentDidMount() {
this.getAllMoviesForMainPage();
}
getAllMoviesForMainPage() {
axios.get("http://localhost:8080/showAll")
.then(response => {
this.setState({ movies: response.data, loading: false })
})
}
render() {
const { loading, movies } = this.state;
if (loading) {
return <div>Loading...</div>;
} else {
return (
<div>
{movies.length > 0 ? (
<div>First movie title: {movies[0].title}</div>
) : (
<div>No movies</div>
)}
</div>
);
}
}
}
您可以使用伪造的 api 来检查此示例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.