繁体   English   中英

我无法从 this.state 获取数据

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM