I am rebuilding a static website in react https://movie-list-website-wt.netlify.app/ I am trying to transfer the search function to react. My current search function works as intended, it returns an array of movies that is being searched, I want it to update the data fetched by the movie cards so that when I search a query, the movie cards use the returned search data instead of the original one this is my App.js file
import React, { useEffect, useState } from 'react'; import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; import Movies from './components/Movies'; import Topnav from './components/Topnav'; import './App.css'; import './components/Movies.css'; export const API_KEY = 'api_key=247b6aa143f3f2c0b100c0cbdfb1ac99'; export const BASE_URL = 'https://api.themoviedb.org/3'; export const API_URL = BASE_URL + '/discover/movie?sort_by=popularity.desc&' + API_KEY; export const IMG_URL = 'https://image.tmdb.org/t/p/w500'; export const searchURL = BASE_URL + '/search/movie?'+ API_KEY; function App() { const [movies, setMovies] = useState ([]); useEffect(() => { fetch (API_URL) .then(res => res.json()) .then(data => { console.log(data); setMovies(data.results); }); }, []) return ( <> <Router> <Topnav /> <div className="movie-container"> {movies.length > 0 && movies.map((movie) => ( <Movies key={movie.id} {...movie} />))} </div> <Routes> <Route exact path='/' /> </Routes> </Router> </> ); } export default App;
and this is part of my Top navigation component that includes the search bar and function
import React, { useState } from 'react'; import { Link } from 'react-router-dom'; import './Topnav.css'; import { searchURL } from '../App'; function Topnav() { const [click, setClick] = useState(false) const handleClick = () => setClick(!click) const modeToggle = () => { document.body.classList.toggle('dark') } const [query, setQuery] = useState("") const onChange = (e) => { e.preventDefault(); setQuery(e.target.value) fetch(searchURL+`&language=en-US&page=1&include_adult=false&query=${e.target.value}`) .then((res) => res.json()) .then((data) => { console.log(data.results); }) } return ( <> <nav className="topnav"> <div className="topnav-container"> <Link to='/' className='topnav-logo'> <img src={require('../img/logo.png').default} alt="logo" /> </Link> <div className="wrapper"> <form id='search-bar'> <input type="text" placeholder="Search" className="search" id="search" value={query} onChange={onChange} /> </form> <label className="switch"> <input type="checkbox" id="mode-toggle" onChange={modeToggle}/> </label> </div>
Advertisement
Answer
If you need to filter the movies
array in the Topnav
component you can just pass the setMovies
state function as prop to the component.
All you need to do is update the data in the onChange
method:
App.js
return ( <> <Router> <!-- Pass the prop to the component --> <Topnav setMovies={setMovies}/> <div className="movie-container"> {movies.length > 0 && movies.map((movie) => ( <Movies key={movie.id} {...movie} />))} </div> <Routes> <Route exact path='/' /> </Routes> </Router> </> );
Topnav.js
function Topnav({ setMovies }) { ... const onChange = (e) => { e.preventDefault(); setQuery(e.target.value) fetch(searchURL+`&language=en-US&page=1&include_adult=false&query=${e.target.value}`) .then((res) => res.json()) .then((data) => { console.log(data.results); // Update the data once fetched setMovies(data.results) }) } ...