You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中如何通过select下拉按分类筛选展示对应电影数据

分类筛选失效的核心问题

你的代码里有4个直接导致功能异常的逻辑错误:

  • 分类字段取值错误:示例数据里genres本身就是字符串数组(如["Adventure", "Comedy"]),不是带genre属性的对象数组,你写的currData.genres.map(rating => rating.genre)拿到的全是undefined,根本无法匹配。
  • 匹配逻辑错误:就算正确拿到分类数组,直接用数组和字符串做==比较永远返回false。一部电影可能对应多个分类,需要判断选中的分类值是否存在于当前电影的分类数组中。
  • 状态设计错误:
    1. 下拉框绑定的genre状态本该存选中的分类字符串值,你却把筛选后的电影结果数组存进去,直接导致下拉框选中值异常;
    2. 文本搜索时直接覆盖原始电影数据,搜一次之后全量数据就丢失,后续筛选只能在之前的搜索结果里执行,无法重置回全量数据;
    3. 分类大小写不匹配:下拉选项的value全是小写(如comedy),原始数据分类是首字母大写(如Comedy),直接比较必然匹配失败。
  • 渲染逻辑错误:页面一直遍历原始movies数组,根本没有用到分类筛选后的结果,就算筛选逻辑写对,页面也不会更新。

修复方案

1. 重写App.js的状态和筛选逻辑

核心思路是单独存储全量原始数据,所有筛选都基于全量数据执行,筛选结果单独存用于渲染,修正分类匹配逻辑:

function App() {
  // 存储接口返回的全量原始电影数据,初始化用空数组而非空字符串
  const [allMovies, setAllMovies] = useState([]);
  const [searchTerm, setSearchTerm] = useState("");
  // 存储下拉框选中的分类值
  const [selectedGenre, setSelectedGenre] = useState("");
  // 存储最终要渲染的筛选结果
  const [filteredMovies, setFilteredMovies] = useState([]);

  // 统一处理文本+分类的组合筛选
  const updateFilteredMovies = (keyword, genre) => {
    let result = [...allMovies];
    // 文本关键词过滤
    if (keyword.trim()) {
      result = result.filter(movie => 
        movie.title.toLowerCase().includes(keyword.trim().toLowerCase())
      );
    }
    // 分类过滤:统一转小写消除大小写差异,只要电影包含选中分类就保留
    if (genre) {
      result = result.filter(movie => 
        movie.genres.some(g => g.toLowerCase() === genre.toLowerCase())
      );
    }
    setFilteredMovies(result);
  };

  const searchMovie = (e) => {
    e.preventDefault();
    updateFilteredMovies(searchTerm, selectedGenre);
  };

  const changeCategory = (e) => {
    const currentGenre = e.target.value;
    setSelectedGenre(currentGenre);
    updateFilteredMovies(searchTerm, currentGenre);
  };

  useEffect(() => {
    const loadMovieInfo = async () => {
      try {
        const response = await axios.get("http://localhost:5000/movies");
        setAllMovies(response.data);
        // 初始加载完成默认展示全量电影
        setFilteredMovies(response.data);
      } catch (err) {
        console.log(err);
      }
    };
    loadMovieInfo();
  }, []);

  // 传递筛选后的结果给列表组件
  return (
    <MovieList 
      movies={filteredMovies}
      searchTerm={searchTerm}
      setSearchTerm={setSearchTerm}
      searchMovie={searchMovie}
      genre={selectedGenre}
      changeCategory={changeCategory}
    />
  );
}

2. 修复MovieList组件的细节问题

  • 表单提交事件绑定到onSubmit而非onClick,支持回车触发搜索:
    <form onSubmit={searchMovie}>
    
  • 列表遍历优先用movie.id作为key,不要用数组index,避免渲染异常;空的<></>碎片标签如果在循环里需要加key,否则直接删除即可。
  • 同一个页面不要给多个元素用相同id(比如你给多个h3都加了id="moviePlot"),换成class即可。
  • 修正下拉选项的拼写和value值:比如mystry正确拼写是Mystery,scifi对应的value要和后端返回的分类值统一(如果后端返回Sci-Fi,option的value就写sci-fi),否则会出现匹配遗漏。

内容的提问来源于stack exchange,提问作者AFB

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 14:15:41