开发者问题收集

无法触发电影 API 项目的搜索功能,因为 useState 位于不同的组件中

2021-07-19
696

我的问题是,我的 App.js 项目有两个不同的组件。这是一个电影数据库,我在首页上有一个电影列表,我可以使用搜索栏搜索其他电影。由于我有 search.js 和 movie.js(我获取 api 数据并显示的组件),search.js 不会触发,因为它无法确定需要更改的内容。基本上我的问题是提交时没有任何变化。

search.js 代码:

import { useState } from 'react';
import React from 'react';

// search API used to search through database
const searchUrl = "https://api.themoviedb.org/3/search/movie?api_key=d62e1adb9803081c0be5a74ca826bdbd&query="


const Search = ({  }) => {
const [movies, setMovies] = useState([]);
const [search, setSearch] = useState("");


 // Search form that fetches search API and returns results
  const submitForm = (e) => {
    e.preventDefault();
  
  // API used to search for any movie in the database
    fetch(searchUrl + search)
      .then(res => res.json())
      .then(data => {
        setMovies(data.results);
      })
    setSearch("");}
  
  // user search input
  const searchQuery = (e) => {
    setSearch(e.target.value)
  }


    return (
      
    <form onSubmit={submitForm}>
    <i class="fas fa-search"></i>
    <label className="sr-only" htmlFor="searchMovie">Search for a movie</label>
    <input
      className="search"
      type="search"
      placeholder="Search for a movie.."
      value={search}
      onChange={searchQuery}
      />
    </form>

    
    
    
    )
}

export default Search;

和我的 movie.js

import { Link } from 'react-router-dom';
import { useState, useEffect } from "react";

const images = "https://image.tmdb.org/t/p/w500/";

// main API used to display trending page
const apiUrl = `https://api.themoviedb.org/3/movie/now_playing?api_key=d62e1adb9803081c0be5a74ca826bdbd&page=`;


const Movie = ( {
}) => {
const [movies, setMovies] = useState([]);


useEffect(() => {
    fetch(apiUrl)
      .then((res) => res.json())
      .then((data)=> {
        setMovies(data.results)
      })
  }, []);


    return (
    <section className="movieslist">
      {movies.length > 0 ? movies.map((movie) => {
        return (
        <Link to={`/movie/${movie.id}`}>
        <div className="moviePoster">
            <img src={movie.poster_path ? `${images}${movie.poster_path}` : "https://www.movienewz.com/img/films/poster-holder.jpg"} alt={movie.title} />
            <div className="movieInfo">
                <h2>{movie.title}</h2>
                <p className="voteStyle">Rating: {movie.voteAverage}</p>
                <p className="release">Release Date: {movie.release}</p>
                <p className="summary">{movie.overview}</p>
                <p className="key">{movie.id}</p>
            </div>

        </div>
        </Link>
          
        );
      }): <p class="noResults">No results found. Please try again?</p>}
        </section>


    )
}


export default Movie;
1个回答

如果我正确理解了预期行为,则您正在尝试从 search.js 更新 movies.js 中的 movies 状态。

您正在更新两个不同组件的两个不同状态,这两个组件彼此之间没有任何关系,因此提交时没有任何反应。

您需要一个父组件(例如 home.js),它将搜索和电影组件作为子组件保存,并保存电影状态。子组件应使用并更新父组件的电影状态。

import Movies from "./movies";
import Search from "./search";

const Home = ()=>{
const [movies, setMovies] = useState([]);
// some other code

return (
    <>
        <Search onSearh={setMovies} />
        <Movies movies={movies} onMovies={setMovies}/>
    </>);
}

并且您的 movies.js 和 search.js 应使用这些 props

import { useState } from 'react';
import React from 'react';

// search API used to search through database
const searchUrl = "https://api.themoviedb.org/3/search/movie?api_key=d62e1adb9803081c0be5a74ca826bdbd&query="


const Search = ({ onSearch }) => {
const [search, setSearch] = useState("");


 // Search form that fetches search API and returns results
  const submitForm = (e) => {
    e.preventDefault();
  
  // API used to search for any movie in the database
    fetch(searchUrl + search)
      .then(res => res.json())
      .then(data => {
        onSearch(data.results);
      })
    setSearch("");}
 

...
import { Link } from 'react-router-dom';
import { useState, useEffect } from "react";

const images = "https://image.tmdb.org/t/p/w500/";

// main API used to display trending page
const apiUrl = `https://api.themoviedb.org/3/movie/now_playing?api_key=d62e1adb9803081c0be5a74ca826bdbd&page=`;


const Movie = ( {movies, onMovies}) => {

useEffect(() => {
    fetch(apiUrl)
      .then((res) => res.json())
      .then((data)=> {
        onMovies(data.results)
      })
  }, []);


...

Imanpal Singh
2021-07-19