React中如何通过onClick实现组件/区块间的电影数据传递?
问题描述
我正在开发一款电影应用,想添加一个onClick函数,把电影卡片里的电影数据传递到Hero区域。我是React新手,不知道怎么解决,也找不到合适资料。目前已经创建了Carousel组件,从App.js接收电影数据作为props,Hero区域也在Carousel组件内,希望在该区块展示数据。
我的代码如下:
function TestCarousel({items}) { //state const [Title, setTitle] = useState([items.original_title]) // function function movieTitle(e) { console.log('click'); } // Use Effect useEffect(() => { movieTitle(); }, []) return ( <div className="main-container"> <div className="hero"> <img src={Image} className="hero-img" /> <div className="movie-details"> <h1>Title</h1> <p>Movie Description</p> </div> </div> <div className="cards"> {items.map((image, index) => ( <div className="movie-card"> <img src={'https://image.tmdb.org/t/p/w500' + image.poster_path} className='movie-img' onClick={movieTitle}/> {/* <h5 className='movie-card-desc'>{image.original_title}</h5> */} {/* <p className='movie-card-overview'>{movie.overview}</p> */} </div> ))} </div> </div> ); }
界面效果:
解决方法
1. 调整状态定义
Hero区域需要展示电影的标题、海报、描述等完整信息,所以应该定义状态存储选中的完整电影对象,初始值可以设为items数组的第一个元素(默认展示第一部电影):
const [selectedMovie, setSelectedMovie] = useState(items[0] || {});
2. 修改点击事件函数
让点击函数接收当前点击的电影数据,直接更新状态:
function handleMovieClick(movie) { setSelectedMovie(movie); }
3. 绑定点击事件到电影卡片
在map渲染卡片时,通过箭头函数把当前电影对象传给点击函数:
<img src={`https://image.tmdb.org/t/p/w500${movie.poster_path}`} className='movie-img' onClick={() => handleMovieClick(movie)} alt={movie.original_title} />
4. 在Hero区域展示选中的电影数据
把Hero里的静态内容替换成状态中的电影数据,同时做空值判断避免报错:
<div className="hero"> {selectedMovie.poster_path && ( <img src={`https://image.tmdb.org/t/p/w1280${selectedMovie.poster_path}`} className="hero-img" alt={selectedMovie.original_title} /> )} <div className="movie-details"> <h1>{selectedMovie.original_title || '请选择一部电影'}</h1> <p>{selectedMovie.overview || '暂无描述'}</p> </div> </div>
5. 清理冗余代码
原来的useEffect调用movieTitle没有实际作用,直接删除即可;同时给map渲染的元素加上key属性,符合React列表渲染规范。
完整修改后的代码
import { useState } from 'react'; function TestCarousel({items}) { // 存储选中的完整电影对象 const [selectedMovie, setSelectedMovie] = useState(items[0] || {}); // 处理电影卡片点击事件 function handleMovieClick(movie) { setSelectedMovie(movie); } return ( <div className="main-container"> <div className="hero"> {selectedMovie.poster_path && ( <img src={`https://image.tmdb.org/t/p/w1280${selectedMovie.poster_path}`} className="hero-img" alt={selectedMovie.original_title} /> )} <div className="movie-details"> <h1>{selectedMovie.original_title || '请选择一部电影'}</h1> <p>{selectedMovie.overview || '暂无描述'}</p> </div> </div> <div className="cards"> {items.map((movie, index) => ( <div className="movie-card" key={index}> <img src={`https://image.tmdb.org/t/p/w500${movie.poster_path}`} className='movie-img' onClick={() => handleMovieClick(movie)} alt={movie.original_title} /> {/* 取消注释可显示卡片上的电影标题 */} {/* <h5 className='movie-card-desc'>{movie.original_title}</h5> */} </div> ))} </div> </div> ); } export default TestCarousel;
核心说明
- 用状态存储完整电影对象,方便后续扩展展示更多信息
- 通过箭头函数传递点击的电影数据,避免直接调用函数导致的执行时机问题
- 空值判断防止初始数据为空或电影信息缺失时出现页面报错
- 添加
key属性满足React列表渲染的性能优化要求
内容的提问来源于stack exchange,提问作者Gavin Walsh
相关产品推荐
相关产品推荐

