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

React电影应用Fetch API搜索仅支持完整词汇问题排查

解决React电影应用搜索仅支持完整词汇的问题

问题根源

YTS.mx的query_term参数默认执行精确匹配,只有当输入的关键词完全匹配电影标题、演员或导演名称时才会返回结果,因此输入jur这类部分词汇无法命中数据。

解决方案:前端本地模糊过滤

先获取一批基础电影数据(比如按年份排序的最新电影),之后在前端根据输入的关键词对电影标题进行模糊匹配,这样就能实现部分词汇的搜索效果。同时优化代码中的其他问题:

修改后的代码如下:

import { useEffect, useState, useCallback } from "react"
import Movie from "../components/Movie"

function Home() {
  const [loading, setLoading] = useState(true)
  const [allMovies, setAllMovies] = useState([]) // 存储所有加载的电影
  const [filteredMovies, setFilteredMovies] = useState([]) // 存储过滤后的电影
  const [searchTerm, setSearchTerm] = useState("")

  // 获取初始电影数据
  const getMovies = async () => {
    try {
      const response = await fetch(
        "https://yts.mx/api/v2/list_movies.json?sort_by=year&limit=50" // 加载更多电影提升搜索体验
      )
      const json = await response.json()
      setAllMovies(json.data.movies || [])
      setFilteredMovies(json.data.movies || [])
    } catch (error) {
      console.error("获取电影数据失败:", error)
      setAllMovies([])
      setFilteredMovies([])
    } finally {
      setLoading(false)
    }
  }

  // 防抖处理搜索过滤
  const filterMovies = useCallback((term) => {
    if (!term) {
      setFilteredMovies(allMovies)
      return
    }
    const filtered = allMovies.filter(movie => 
      movie.title.toLowerCase().includes(term.toLowerCase())
    )
    setFilteredMovies(filtered)
  }, [allMovies])

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

  useEffect(() => {
    // 添加防抖,避免输入过程中频繁过滤
    const timer = setTimeout(() => {
      filterMovies(searchTerm)
    }, 300)
    return () => clearTimeout(timer)
  }, [searchTerm, filterMovies])

  const inputHandler = (e) => {
    setSearchTerm(e.target.value)
  }

  return (
    <div className="App">
      <input
        onChange={inputHandler}
        value={searchTerm}
        placeholder="搜索电影..."
      />
      {loading ? (
        <h1>Loading...</h1>
      ) : (
        <div>
          {filteredMovies.length === 0 && searchTerm && (
            <p>未找到匹配的电影</p>
          )}
          {filteredMovies.map((movie) => (
            <Movie
              key={movie.id}
              id={movie.id}
              coverImg={movie.medium_cover_image}
              title={movie.title}
              year={movie.year}
              rating={movie.rating}
            />
          ))}
        </div>
      )}
    </div>
  )
}

export default Home

代码优化点说明

  • 拆分电影数据存储:用allMovies保存初始加载的所有电影,filteredMovies保存搜索后的结果,避免重复请求API。
  • 添加防抖:设置300ms延迟,减少输入过程中的频繁过滤操作,提升性能。
  • 错误处理:用try/catch捕获API请求异常,避免页面崩溃。
  • 修复加载状态:用finally确保无论请求成功或失败都关闭加载状态,替换原有的错误数组比较逻辑。
  • 空状态提示:当搜索无结果时,给用户明确提示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 16:57:22