【问题标题】:(React)Filter through api by search term(React)通过 api 按搜索词过滤
【发布时间】:2021-07-04 13:21:53
【问题描述】:

我正在尝试在我的 React 项目中使用搜索栏组件来按标题搜索/过滤电影的 api 列表。现在我的搜索词是控制台日志记录,但我正在尝试过滤电影列表以仅显示与该词匹配的标题。我在使用术语更新电影状态和显示新数组时遇到问题。

应用程序

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

搜索栏组件

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;

【问题讨论】:

    标签: javascript arrays reactjs api search


    【解决方案1】:

    首先需要额外的状态来记录加载的动作列表:

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

    最好使用useCallback 声明处理程序,并避免混合使用声明式和命令式样式。例如:

    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/

    【讨论】:

    • 非常感谢!这行得通!我需要学习 useRef 和 UseCallback :)
    • 最后一个问题,如果我有另一个选项选择表单并且我想按流派过滤,它会是相同的结构吗?还是我需要设置第三种状态?
    • 每部电影的流派都是一个数组
    • 是的,在大多数情况下,最好为每个单数字段声明 useState。但是,如果您要引入一堆字段(某种搜索表单),最好使用一些表单管理库。例如,formik.org/docs/overview
    • 我不断收到“未定义包含”我这样做对吗?
    猜你喜欢
    • 1970-01-01
    • 2017-09-04
    • 1970-01-01
    • 2018-10-25
    • 2023-04-07
    • 2023-01-19
    • 1970-01-01
    • 2012-02-17
    • 1970-01-01
    相关资源
    最近更新 更多