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
相关产品推荐
相关产品推荐

