JuniorDev
JuniorDev

Reputation: 53

(React)Filter through api by search term

I'm trying to use a search bar component in my React project to search/filter through an api list of movies by title. Right now my search term is console logging, but i'm trying to filter the movie list to only show the titles that match the term. I'm having issues with updating my movies state with the term and displaying the new array.

App

import SearchBar from "../Search/SearchBar"

export default function Movies() {
  const [movies, setMovies] = useState([]);

  async function getMovies() {
    const movieData = await fetchMovies();

    console.log(movieData);
    setMovies(
      movieData.data.data.sort((a, b) => a.title.localeCompare(b.title))
    );
  }

  useEffect(() => {
    getMovies();
  }, []);

 async function onSearchSubmit(term) {
    console.log(term)
    let fill = []
    movies.filter((movie) => {
        if(movie.title === term) {
           fill.push(movie.title)
        }
       setMovies(fill)

    })
    }

  return (
    <>
      <Nav 
      movies={movies}
      setMovies={setMovies}/>
      <SearchBar
      onSubmit={onSearchSubmit}/>

      {movies ? (
        <div>
          <div>
            {movies.map((m, idx) => {
              return <div key={idx}>{m.title}</div>;
            })}{" "}
          </div>
        </div>
      ) : (
        "loading..."
      )}
    </>
  );
}

Search Bar component

import React,{useState} from 'react';

const SearchBar = ({onSubmit}) => {

    const [term, setTerm] = useState("")


    function onFormSubmit(event){
        event.preventDefault()
        onSubmit(term)
        
        }

    return ( 
        
        <div className="ui segment">
        <form onSubmit={onFormSubmit} className="ui form">
          <div className="field">
            <label>Movie Search</label>
            <input
              type="text"
              value={term}
              onChange={(e) => setTerm( e.target.value)}
            />
          </div>
        </form>
      </div>
     );
}
 
export default SearchBar;

Upvotes: 0

Views: 559

Answers (1)

Alexander Alexandrov
Alexander Alexandrov

Reputation: 1362

First of all additional state is needed to record the loaded moves list:

const movies = useRef([]);
const [filteredMovies, setFilteredMovies] = useState([]);

It is better to declare handlers with useCallback and avoid the mixture of declarative and imperative styles. For example:

const onSearchSubmit = useCallback(async (term) => {
  if (term) {
    const _ = movies.current.filter(({ title }) => (title === term));
    setFilteredMovies(_);
  } else {
    setFilteredMovies(movies.current);
  }
}, [movies]);

https://jsfiddle.net/pq9xkewz/2/

Upvotes: 1

Related Questions