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

如何通过按钮过滤两个不同API返回的影视数据?

如何实现电影/电视剧内容的切换过滤功能(双API数据源)

我想给项目加个按钮过滤功能:点「电视剧」按钮显示剧集内容,点「电影」按钮显示对应内容。目前数据来自两个不同的API调用,我已经有过滤单个数组属性的功能,但没法直接复用。想问下能不能把两类数据合并到同一数组后按属性过滤,或者有没有更优的解决方案?

我的API调用代码如下:

function App() {
  // State 
  const [kidsMovies, setKidsMovies] = useState([])
  const [kidsTv, setKidsTv] = useState([])

  // API URL 
  const kidsMovieURL = 'https://api.themoviedb.org/3/discover/movie?api_key=&certification_country=US&certification.lte=G&with_genres=16&include_adult=false&sort_by=popularity.desc';
  const kidsTvURL = 'https://api.themoviedb.org/3/tv/popular?api_key=&language=en-US&page=1&with_genres=16&include_adult=false&sort_by=popularity.desc';

  // Async function to fetch API
  async function getMoviesData (kidsMovieURL, kidsTvUrl) {
    await fetch(kidsMovieURL).then(res => res.json()).then(data => setKidsMovies(data.results))
    await fetch(kidsTvUrl).then(res => res.json()).then(data => setKidsTv(data.results))
  }

  // Use Effect 
  useEffect(() => { 
    getMoviesData(kidsMovieURL, kidsTvURL);
  }, [])
}

解决方案

方案一:合并为带类型标记的统一数组(推荐复用现有过滤逻辑)

如果想复用你已有的单数组过滤功能,最直接的方式是给两类数据加上统一的类型标记,合并成一个数组,再通过状态控制要显示的类型:

  1. 修改状态结构,用一个数组存储所有媒体内容,再加一个状态控制当前激活的类型:
const [mediaItems, setMediaItems] = useState([]);
const [activeType, setActiveType] = useState('movie'); // 默认显示电影
  1. 优化API请求(改成并行请求提升效率),给每条数据添加type字段后合并:
async function getMediaData() {
  // 并行发起两个请求,比串行await更快
  const [movieRes, tvRes] = await Promise.all([
    fetch(kidsMovieURL).then(res => res.json()),
    fetch(kidsTvURL).then(res => res.json())
  ]);
  
  // 给电影数据加type标记
  const formattedMovies = movieRes.results.map(item => ({
    ...item,
    type: 'movie'
  }));
  
  // 给电视剧数据加type标记
  const formattedTv = tvRes.results.map(item => ({
    ...item,
    type: 'tv'
  }));
  
  // 合并成统一数组
  setMediaItems([...formattedMovies, ...formattedTv]);
}

useEffect(() => {
  getMediaData();
}, []);
  1. 渲染时根据activeType过滤,同时可以复用你现有的单数组过滤逻辑:
// 过滤当前要显示的内容
const currentContent = mediaItems.filter(item => item.type === activeType);

// 按钮切换逻辑
return (
  <div>
    <button onClick={() => setActiveType('movie')}>电影</button>
    <button onClick={() => setActiveType('tv')}>电视剧</button>
    
    {/* 渲染currentContent */}
    <div className="content-grid">
      {currentContent.map(item => (
        // 根据type区分渲染逻辑(如果需要)
        <div key={item.id} className="media-card">
          {item.type === 'movie' ? <h3>{item.title}</h3> : <h3>{item.name}</h3>}
          {/* 其他内容渲染 */}
        </div>
      ))}
    </div>
  </div>
);

方案二:保留分开的数组,直接切换数据源

如果不需要合并数据,也可以直接通过状态切换要渲染的数组,这种方式更轻量,不需要修改原有数据结构:

  1. 添加状态控制当前激活的标签:
const [activeTab, setActiveTab] = useState('movie');
  1. 渲染时根据activeTab选择对应的数组:
const currentContent = activeTab === 'movie' ? kidsMovies : kidsTv;

return (
  <div>
    <button onClick={() => setActiveTab('movie')}>电影</button>
    <button onClick={() => setActiveTab('tv')}>电视剧</button>
    
    <div className="content-grid">
      {currentContent.map(item => (
        <div key={item.id} className="media-card">
          {/* 注意电影用title,电视剧用name,需要区分 */}
          <h3>{activeTab === 'movie' ? item.title : item.name}</h3>
          {/* 其他内容渲染 */}
        </div>
      ))}
    </div>
  </div>
);

额外优化建议

  • 把API请求改成Promise.all并行执行,比原来的串行await更高效,减少加载时间;
  • 可以给按钮添加激活状态样式,让用户知道当前选中的是哪个标签;
  • 如果后续需要更复杂的过滤(比如结合类型+其他属性),方案一的统一数组结构会更灵活。

内容的提问来源于stack exchange,提问作者Gavin-walsh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 09:55:21