#javascript #reactjs #api
#javascript #reactjs #API
Вопрос:
Я пытаюсь создать приложение для поиска фильмов с помощью React и сделал вызов API для API базы данных фильмов. У меня есть эта форма, и то, что я пытаюсь сделать, это получить данные фильма, который я ищу.
Я не могу получить доступ к данным из вызова API, и я получаю эту ошибку «Uncaught TypeError: не удается прочитать свойство ‘map’ неопределенного»
У меня есть два js-файла: 1 index.js
import React from 'react';
import ReactDOM from 'react-dom';
import SearchMovies from "./searchMovies";
import './style.css';
class Main extends React.Component {
render() {
return (
<div className="container">
<h1 className="title">React Movie Search</h1>
<SearchMovies/>
</div>
);
}
}
ReactDOM.render(<Main />, document.getElementById('root'));
Второй файл searchMovies.js
import React, {useState} from "react";
export default function SearchMovies(){
//states- input query, movies
const [query, setQuery] = useState('');
const [movies, setMovies] = useState([]);
const searchMovies = async (e) => {
e.preventDefault();
const url = `https://api.themoviedb.org/3/movie/550?
api_key=api_keyamp;language=en-USamp;query=${query}amp;page=1amp;
include_adult=false`;
try {
const res = await fetch(url);
const data = await res.json();
setMovies(data.results);
}catch(err){
console.error(err);
}
}
return(
<div>
<form className="form" onSubmit={searchMovies}>
<label htmlFor="query" className="Label">Movie Name</label>
<input className="input" type="text" name="query" placeholder="i.e. Jurassic
Park"
value={query} onChange={(e) => setQuery(e.target.value)}
/>
<button className="button" type="submit">Search</button>
</form>
<div className="card-list">
{movies.map(movie => (
<div className="card">
<img className="card--image"
src={`https://image.tmdb.org/t/p/w185_and_h278_bestv2/
${movie.poster_path}`}
alt={movie.title ' poster'}
/>
</div>
))}
</div>
</div>
)
}
Может кто-нибудь сказать мне, что я здесь делаю не так? Я новичок в React.
Большое спасибо!
Комментарии:
1. Просто проверьте, что это
data.results
массив, потому что, если это не массив, тогда появится ошибка.
Ответ №1:
Ваш API отвечает на объект, а не на массив, поэтому функция map не работает.
Посмотрите ваш ответ API:
{«adult»:false,»backdrop_path»:»/rr7E0NoGKxvbkb89eR1GwfoYjpA.jpg»,»belongs_to_collection»:null,»budget»:63000000,»genres»:[{«id»:18,»name»:»Drama»}],»homepage»:»http://www.foxmovies.com/movies/fight-club»,»id»: 550,»imdb_id»:»tt0137523″,»original_language»:»ru», «original_title»:»Бойцовский клуб»,»обзор»: «Бессонница с бомбой замедленного действия и скользкий продавец мыла превращают первобытную мужскую агрессию в новую шокирующую форму терапии. Их концепция завоевывает популярность, в каждом городе формируются подпольные «бойцовские клубы», пока на пути не встает эксцентрик и не запускает неконтролируемую спираль к забвению.»,»popularity»:46.801,»poster_path»:»/pB8BM7pdSp6B6Ih7QZ4DrQ3PmJK.jpg»,»production_companies»:[{«id»:508,»logo_path»:»/7PzJdsLGlR7oW4J0J5Xcd0pHGRg.png»,»name»:» Regency Enterprises»,»origin_country»: «США»},{«id»: 711,»logo_path»:»/tEiIH5QesdheJmDAqQwvtN60727.png»,»name»:»Fox 2000 Pictures»,»origin_country»:»US»},{«id»: 20555,»logo_path»:»/hD8yEGUBlHOcfHYbujp71vD8gZp. png»,»название»: «Taurus Film»,»origin_country»:»DE»},{«id»: 54051,»logo_path»: null,»name»:»Atman Entertainment»,»origin_country»:»»},{«id»: 54052,»logo_path»: null, «name»:»KnickerbockerФильмы»,»origin_country»:»US»},{«id»: 25,»logo_path»:»/qZCc1lty5FzX30aOCVRBLzaVmcp.png»,»name»: «20th Century Fox»,»origin_country»:»US»},{«id»: 4700,»logo_path»:»/A32wmjrs9Psf4zw0uaixF0GXfxq.png»,»name»: «Линсон Company»,»origin_country»:»»}],»production_countries»:[{«iso_3166_1″:»DE»,»name»:»Germany»},{«iso_3166_1″:»US»,»name»:»Соединенные Штаты America»}],»release_date»:»1999-10-15″,»revenue»:100853753,»runtime»:139,»spoken_languages»:[{«iso_639_1″:»en»,»name»:»English»}],»status»:»Выпущено»,»слоган»: «Вред. Хаос. Soap.»,»title»:»Бойцовский клуб»,»video»: false,»vote_average»:8.4,»vote_count»:20153}
Комментарии:
1. И у вас есть решение?
2. Ваша фактическая ссылка на API ниже. Этот URL-адрес работает правильно.
https://api.themoviedb.org/3/search/movie?api_key=fedbe6a180fedfbf90f45a61bc8d62d0amp;language=en-USamp;query=${query}amp;page=1amp;include_adult=false
Ответ №2:
Я сделал jsfiddle с вашим кодом для тестирования: https://jsfiddle.net/hqm6rcpf /
const url = `https://api.themoviedb.org/3/movie/550?
api_key=api_keyamp;language=en-USamp;query=${query}amp;page=1amp;
include_adult=false`;
Этот код недопустим. Вы не можете добавлять разрывы строк в URL.
Изменив это, я смог заставить его работать:
const url = `https://api.themoviedb.org/3/search/movie?api_key=api_keyamp;language=en-USamp;query=${query}amp;page=1amp;include_adult=false`;
Комментарии:
1. Я попробовал ваш код, и он не работает, у меня та же ошибка.
2. Я понятия не имею, почему мой локальный проект не работает, я добавил ваш код, и у меня все та же ошибка… Это расстраивает.
3. Мой плохой, Xurei! Я не знаю, что я делал раньше, но теперь работает! Потрясающе!
Ответ №3:
прежде всего, никогда не делитесь своим личным ключом api в Интернете!!
const data = await res.json();
Зачем снова использовать await, когда вы уже извлекли данные?
кроме того, если ответ json, это JSON.parse (res) .
Далее, вы действительно просмотрели данные, которые вы получаете? Попробуйте записать его в консоль. Насколько я могу судить, это объект, а не массив, поэтому вы не можете использовать map.
Комментарии:
1. Эй, Янник, тебе нужно добавить await, потому
res.json()
что вернет обещание, тогдаJSON.parse
как не вернет обещание, поэтому нам не нужно await2. Итак, когда я добавил эту строку кода в searchMovies.js «const [movies, setMovies] = useState([]); » это был первый раз, когда у меня возникла ошибка.
3. Ну да, потому что вы устанавливаете состояние movies для ответа на запрос выборки, поэтому, если ответ не является массивом. Функция map вызывает ошибку. Попробуйте записать в консоль свою переменную данных перед запуском setMovies.
4. Янник, я зарегистрировал его на консоли, и вы правы, это объект.