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

React中如何跨页面传递收藏电影数组至收藏页

问题根源
  • 你的favouriteMovies状态定义在Home组件内部,属于组件级私有状态:
    1. 切换路由离开Home页面时,Home组件会被卸载,存在这里的收藏数据会直接丢失
    2. Favourites组件和Home是平级路由,无法直接访问Home的内部状态
  • 原有handleFavourites逻辑不符合React状态更新规则:直接用push修改原state数组不会触发React重渲染,页面不会同步更新,必须通过setFavouriteMovies生成新数组才能驱动视图更新。
解决方法(状态提升,零额外依赖)

把收藏相关的状态和操作方法提升到两个路由的公共父组件App.js中,再通过props把状态和方法传给需要的子组件,这是React官方推荐的跨平级组件共享状态方案。

第一步:修改App.js

把收藏状态、收藏操作方法都定义在App层,传给对应路由组件:

import React, { useState } from "react";
import Header from "./Header";
import {Route, Routes} from 'react-router-dom'
import Favourites from "./views/Favourites";
import Home from "./views/Home";
import About from "./views/About";

function App() {
    // 收藏状态提升到公共父组件
    const [favouriteMovies, setFavouriteMovies] = useState([])

    // 修正收藏逻辑:通过set方法生成新数组触发渲染,加去重逻辑避免重复收藏
    const handleAddFavourite = (movie) => {
        setFavouriteMovies(prev => {
            const isCollected = prev.some(item => item.imdbID === movie.imdbID)
            if(isCollected) return prev
            return [...prev, movie]
        })
    }

    // 收藏页需要的取消收藏方法
    const handleRemoveFavourite = (movieId) => {
        setFavouriteMovies(prev => prev.filter(item => item.imdbID !== movieId))
    }
    
    return (
    <>
        <Header />
        <div>
            <Routes>
                {/* 给首页传添加收藏的方法 */}
                <Route path="/" element={<Home handleAddFavourite={handleAddFavourite} />} />
                {/* 给收藏页传收藏列表、取消收藏方法 */}
                <Route path="/favourites" element={<Favourites favouriteMovies={favouriteMovies} handleRemoveFavourite={handleRemoveFavourite} />} />
                <Route path="/about" element={<About />} />
            </Routes>
        </div>
        
    </>
    )
}

export default App;

第二步:修改Home.js

删除Home内部定义的收藏状态和错误的收藏方法,改用父组件传入的方法:

import React, { useState, useEffect } from 'react';
import SearchField from '../components/SearchField';
import MovieList from '../components/MovieList';

// 接收父组件传入的添加收藏方法
const Home = ({ handleAddFavourite }) => {
     const [movies, setMovies] = useState([]);
     const [searchInput, setSearchInput] = useState ('')
     // 删除原Home内部的favouriteMovies状态、错误的handleFavourites方法

         const getMovies = async (searchInput) => {
             const url = `http://www.omdbapi.com/?s=${searchInput}&apikey=87aa1413`;

             const res = await fetch(url);
             const resJson = await res.json();

             if (resJson.Search){
                 setMovies(resJson.Search)
             }

         };

         useEffect(() => {
             getMovies(searchInput);
         }, [searchInput]);


    return ( 
        <>
             <SearchField searchInput={searchInput} setSearchInput={setSearchInput} />
             {/* 把收藏方法传给电影列表组件 */}
             <MovieList movies = {movies} handleFavourites = {handleAddFavourite}/>
        </>
    )
}

export default Home;

第三步:修改Favourites.js

接收父组件传入的收藏列表,渲染内容即可:

import React from "react"

// 接收父组件传入的收藏列表、取消收藏方法
const Favourites = ({ favouriteMovies, handleRemoveFavourite }) => {
    return ( 
        <>
            <h1>我的收藏</h1>
            <div className="favourite-list">
                {favouriteMovies.length === 0 ? (
                    <p>暂无收藏电影</p>
                ) : (
                    favouriteMovies.map(movie => (
                        <div key={movie.imdbID} className="movie-card">
                            <img src={movie.Poster} alt={movie.Title} />
                            <p>{movie.Title} ({movie.Year})</p>
                            <button onClick={() => handleRemoveFavourite(movie.imdbID)}>取消收藏</button>
                        </div>
                    ))
                )}
            </div>
        </>
    )
}

export default Favourites;
扩展可选方案

如果后续项目组件层级变深,多层props传递太繁琐,可以根据项目规模选择其他方案:

  • 用React Context做全局状态容器,适合中小型项目,无需安装额外依赖
  • 用Zustand、Redux等轻量/标准状态管理库,适合大型项目,全局状态访问更灵活
  • 如果需要刷新页面收藏不丢失,可以在状态更新时同步把收藏列表存入localStorage,初始化状态时优先从本地缓存读取即可。

核心注意点:React状态更新不能直接修改原数组/对象,必须返回新的引用值,React才能检测到状态变化触发重渲染。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 04:24:24