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

React开发电影App:如何实现单部电影卡片Overview内容独立展开/收起

解决电影卡片ShowMore/ShowLess独立控制的问题

这个问题我之前开发类似组件时也碰到过!核心原因很简单:你把readMore状态放在了遍历所有电影的MovieCard组件里,这个状态是所有卡片共享的——不管点击哪个按钮,都会触发这个全局状态的改变,自然所有卡片会一起展开/收起。

下面给你两种实用的解决方案,按需选择:

方案1:拆分独立的单卡片组件(推荐)

把单个电影的卡片抽成独立组件,让每个卡片自己维护readMore状态,这样每个卡片的状态完全独立,互不干扰。

首先创建单卡片组件:

import { useState } from 'react';

const SingleMovieCard = ({ movie, ImgPath }) => {
  // 每个卡片单独拥有自己的展开状态
  const [readMore, setReadMore] = useState(false);
  const { id, title, poster_path, overview } = movie;
  
  return (
    <article key={id} className="card">
      <img src={`${ImgPath}${poster_path}`} alt={title}/>
      <h1>{title}</h1>
      <p>
        {readMore ? overview : `${overview.substring(0, 50)}...`}
        <button onClick={() => setReadMore(!readMore)}>
          {readMore ? "ShowLess" : "ShowMore"}
        </button>
      </p>
    </article>
  );
};

然后修改原来的MovieCard组件,遍历渲染单卡片:

const MovieCard = ({ moviesList, ImgPath }) => {
  return (
    <div className="cards-container"> {/* 可以加个容器优化布局 */}
      {moviesList.map((singleMovie) => (
        <SingleMovieCard 
          key={singleMovie.id} 
          movie={singleMovie} 
          ImgPath={ImgPath} 
        />
      ))}
    </div>
  );
};

export default MovieCard;

这种方式完全符合React的组件设计思路,每个组件只负责自己的状态和UI,代码清晰易懂,后期维护也更方便。

方案2:集中管理每个电影的展开状态(不新增组件)

如果不想拆分组件,你可以用一个对象来存储每个电影ID对应的展开状态,通过ID来精准控制单个卡片的显示。

import { useState } from 'react';

const MovieCard = ({ moviesList, ImgPath }) => {
  // 用对象存储每个电影的展开状态,key是电影ID,value是布尔值
  const [expandedMovies, setExpandedMovies] = useState({});

  // 切换指定ID电影的展开状态
  const toggleReadMore = (movieId) => {
    setExpandedMovies(prevState => ({
      ...prevState,
      [movieId]: !prevState[movieId] // 不存在则默认false,取反变为true
    }));
  };

  return (
    <div className="cards-container">
      {moviesList.map((singleMovie) => {
        const { id, title, poster_path, overview } = singleMovie;
        // 判断当前电影是否展开,默认不展开
        const isExpanded = expandedMovies[id] || false;
        
        return (
          <article key={id} className="card">
            <img src={`${ImgPath}${poster_path}`} alt={title}/>
            <h1>{title}</h1>
            <p>
              {isExpanded ? overview : `${overview.substring(0, 50)}...`}
              <button onClick={() => toggleReadMore(id)}>
                {isExpanded ? "ShowLess" : "ShowMore"}
              </button>
            </p>
          </article>
        );
      })}
    </div>
  );
};

export default MovieCard;

这个方案不需要新增组件,通过集中管理状态实现精准控制,适合不想调整组件结构的场景。

注意:记得确保ImgPath是从父组件正确传入的参数哦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 12:42:31