Can't trigger a search function for movie API project because useState is in a different component

Viewed 304

my problem is that I have two different components belonging to my App.js project. It's a movie database where I have a list of movies on the front page and I can search for other movies using the search bar. Since I have the search.js and movie.js ( component where i fetch api data and display), the search.js will not trigger as it cant pinpoint what needs to change. Basically my problem is that on submit, nothing changes.

search.js code:

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;

and my 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 Answers

If I understand the expected behavior correctly, you're trying to update the movies state in movies.js from the search.js.

You are updating two different states of two different components that have no relationship with themselves and that is why nothing is happening on submit.

What you'll need is a parent component (for example home.js) that holds search and movies component as children and holds the movies state. The child components should use and update the parent's movie state.

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}/>
    </>);
}

and your movies.js and search.js should consume these 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)
      })
  }, []);


...

Related