Необработанный отказ (TypeError): this.state.movie.map не является функцией - PullRequest
0 голосов
/ 06 июня 2018

После нескольких часов поисков и попыток исправить мой код самостоятельно, я не могу заставить это работать или не могу найти четкую документацию по моей конкретной проблеме.Буду признателен за любую помощь!

Я пытаюсь создать приложение для рейтинга фильмов, и я почти дошел до конца.Однако сейчас я пытаюсь отобразить мою информацию из API.У меня есть отдельный компонент «SearchForm.tsx», который обрабатывает поле поиска, которое вызывается в app.tsx после вызова API как «+ SearchForm», которое должно равняться запросу для API.Когда я пытаюсь ввести текст и нажимаю клавишу возврата, я зацикливаюсь на:

"необработанное отклонение (TypeError): this.state.movie.map не является функцией".

Эта проблема возникает в моем приложенииФайл .tsx в строках 46 и 27.

Пример API:

Здесь я пытаюсь отобразить "https://api.themoviedb.org/3/search/movie?api_key=58db259ec7d41d210fee1d1dc69b6fca&query=home"

App.tsx

import axios from "axios";
import * as React from "react";
import "./App.css";
import MoviesList from "./Components/MoviesList";
import SearchForm from "./Components/SearchForm";

export default class App extends React.Component<any, any> {
  constructor(props: any) {
    super(props);
    this.state = {
      loading: true,
      movie: []
    };
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  public handleSubmit(value: any) {
    // const searchInput = value; // you get the value of movieName input here

    const sortByPop = "&sort_by=popularity.desc";
    const requestUrl =
      "https://api.themoviedb.org/3/search/movie?api_key=58db259ec7d41d210fee1d1dc69b6fca&query=" +
      SearchForm +
      sortByPop;

    return axios.get(requestUrl).then(response => {
[27]err this.setState(
        loading: false,
        movie: response.data
      });
      // tslint:disable-next-line:no-console
      console.log(response.data);
    });
  }

  public render() {
    return (
      <div>
        <div className="main-header">
          <div className="inner">
            <h1 className="main-title">Playpilot Assignment</h1>
            <SearchForm onSubmit={this.handleSubmit} />
          </div>
        </div>
        <div className="main-content">
[46]err   {this.state.movie.map(movie => ( 
            <div className="movieTitle">
              <div className="movieCard">
                <img
                  className="posterImg"
                  src={`https://image.tmdb.org/t/p/w185_and_h278_bestv2/${
                    movie.poster_path
                  }`}
                  alt={movie.title}
                />
                <div className="searchFilmTitles" key={movie.id}>
                  {movie.title}
                </div>
              </div>
            </div>
          ))}
          {this.state.loading ? (
            <h2>Loading...</h2>
          ) : (
            <MoviesList data={this.state.moviesList} />
          )}
        </div>
      </div>
    );
  }
}

SearchForm.tsx

import * as React from "react";

export default class SearchForm extends React.Component<any, any> {
  public value: HTMLInputElement | null;
  constructor(props: any) {
    super(props);

    this.state = {
      movie: []
    };

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  public handleChange(event: any) {
    this.setState({ value: event.target.value });
  }

  public handleSubmit(event: any) {
    event.preventDefault();
    if (this.props.onSubmit && typeof this.props.onSubmit === "function") {
      this.props.onSubmit(this.state.value);
    }
  }

  public render() {
    return (
      <form className="search-form" onSubmit={this.handleSubmit}>
        <label className="is-hidden" htmlFor="search">
          Search
        </label>
        <input
          type="search"
          onChange={this.handleChange}
          name="search"
          ref={input => (this.value = input)}
          placeholder="Search..."
        />
        <button type="submit" id="submit" className="search-button">
          <i className="material-icons icn-search" />
        </button>
      </form>
    );
  }
}

MoviesList.tsx

import * as React from "react";
import Movie from "./Movie";

const MoviesList = (props: any) => {
  const results = props.data;
  let movie: any;
[7]err  if (results.data) {
    // tslint:disable-next-line:no-shadowed-variable
    movie = results.map((movie: any) => (
      <Movie url={props.url} key={movie.id} />
    ));
  } else {
    movie = <h1>404: No movies found.</h1>;
  }

  return <ul className="movie-list">{movie}</ul>;
};

export default MoviesList;

Еще раз спасибо за любую помощь!

1 Ответ

0 голосов
/ 06 июня 2018

response.data на самом деле не массив, а объект.Измените свой вызов API следующим образом:

this.setState(
  loading: false,
  movie: response.data.results // results is the array you are looking for.
});

Или, может быть, лучше отобразить результаты в функции рендеринга:

{this.state.movie && this.state.movie.results.map(movie => ( 
    ...
))}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...