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

React中如何向其他组件传递数据:电影站点详情页传参问题

修复方案

核心问题梳理

  • 影片详情拉取逻辑仅绑定在爱心图标上,用户点击海报跳转时不会触发详情接口请求,content一直为空初始值,无法传递有效数据
  • 通过NavLink的state传递的参数不会直接作为详情页组件的props传入,需要从路由的location对象读取
  • 影片视频链接的拉取逻辑直接写在组件顶层,会触发无限重渲染,严重影响性能
  • content初始值设为数组,但接口返回的是电影对象,会引发后续取值报错

具体修改步骤

1. 调整MovieCard组件逻辑

推荐直接传递电影ID到详情页,由详情页自行拉取详情数据,避免跳转时接口还未返回导致数据丢失的问题,修改后代码如下:

import React, {useState, useEffect} from 'react'
import placeholder from '../Assets/Placeholder.jpg'
import {Button, Nav} from 'react-bootstrap'
import '../sass/custom.scss'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faStar, faPlay, faHeart, faShare } from '@fortawesome/free-solid-svg-icons'
import {NavLink} from 'react-router-dom';

export const MovieCard = ({movieresults}) => {
    const [trailer, setTrailer] = useState();

    // 把视频拉取逻辑放到useEffect中,避免无限重渲染
    useEffect(() => {
        fetch(`https://api.themoviedb.org/3/movie/${movieresults.id}/videos?api_key=${process.env.REACT_APP_TMDB_KEY}&language=en-US`)
        .then((res) => res.json())
        .then((data) => {
            if (!data.errors) {
                setTrailer(data.results[0]?.key);   
            }
        })
    }, [movieresults.id])

    // 爱心点击逻辑保留
    const onClick = e => {
        fetch(`https://api.themoviedb.org/3/movie/${movieresults.id}?api_key=${process.env.REACT_APP_TMDB_KEY}&language=en-US`)
        .then((res) => res.json())
        .then((data) => {
            if (!data.errors) {
                console.log(data)
            }
        })
    }

    return (
        <div className="movie-card">
            <div className="poster-container">
                <span className="rating translate-middle rounded-pill">
                    <FontAwesomeIcon icon={faStar} className="star"/>
                    {movieresults.vote_average}
                </span>
            {movieresults.poster_path ? (
                // 直接传递电影ID到详情页
                <Nav.Link as={NavLink} exact={true} to={{pathname:"/film", state: { movieId: movieresults.id } }} className="poster-link" >
                <img className="poster" 
                src={`https://image.tmdb.org/t/p/w300${movieresults.poster_path}`} 
                alt= {movieresults.title}
               />
               </Nav.Link>
            ) : (
                <img className="poster"
                 src={placeholder} 
                 alt= {movieresults.title}
                />
            )}
            </div>
            <div className="content-container">
                <b className="title mobile-text">{movieresults.title}</b>
                <p className="desc mobile-text">{movieresults.release_date}</p>
                <div className="card-btn">
                    <Button className="btn btn-secondary watch-btn" target="__blank" href={`https://www.youtube.com/watch?v=${trailer}`}><FontAwesomeIcon icon={faPlay} /> Trailer</Button>
                    <div className="icons">
                        <a href className="icon-btn"><FontAwesomeIcon icon={faHeart} onClick={onClick}/> </a>
                        <a href className="icon-btn"><FontAwesomeIcon icon={faShare} /> </a>
                    </div>
                </div>
            </div>
        </div>
    )
}

2. 调整FilmPage详情页逻辑

引入useLocation钩子读取路由传递的电影ID,在详情页拉取影片详情数据:

import React, {useState, useEffect} from 'react'
import { Container } from 'react-bootstrap';
import { useLocation } from 'react-router-dom';

export const FilmPage = () => {
    const location = useLocation();
    const [content, setContent] = useState({});
    const movieId = location.state?.movieId;

    useEffect(() => {
        if (!movieId) return;
        // 详情页自行拉取影片数据
        fetch(`https://api.themoviedb.org/3/movie/${movieId}?api_key=${process.env.REACT_APP_TMDB_KEY}&language=en-US`)
        .then((res) => res.json())
        .then((data) => {
            if (!data.errors) {
                setContent(data);   
            }
        })
    }, [movieId])

    return (
        <Container>
            <h1>Film Page</h1>
            {content.id && <h1>{content.id}</h1>}
        </Container>
    )
}

补充说明

如果你确实需要在卡片组件拉取数据后再传递到详情页,需要将点击跳转逻辑替换为手动触发:先调用详情拉取接口,接口返回成功后再调用useNavigate钩子跳转页面,同时把数据放到state中,避免跳转时数据还未返回的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 21:15:09