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

React跨组件状态管理实现:点击MovieItem组件的收藏按钮将影片标题添加至Favorites组件的state

解决React组件间传递电影信息到收藏列表的问题

要实现点击MovieItem的按钮把影片信息添加到Favorites的列表里,核心是解决兄弟组件间的通信问题。因为这两个组件没有直接的父子关系,我们可以通过状态提升到它们的共同父组件(比如App.js)来实现数据传递,这是React中最常用的组件通信方式之一。

步骤1:在共同父组件中管理收藏状态

首先,我们把收藏列表的状态从Favorites移到父组件(比如App),同时定义一个添加收藏的方法,然后把这个方法传给MovieItem,把收藏列表传给Favorites。

// App.js 示例代码
import React, { Component } from 'react';
import MovieItem from './MovieItem';
import Favorites from './Favorites';

class App extends Component {
  state = {
    favorites: [
      { imdbID: 'tt0068646', title: 'The Godfather', year: 1972 }
    ]
  };

  // 添加收藏的方法,接收电影信息作为参数
  addToFavorites = (movie) => {
    // 先检查是否已经在收藏列表里,避免重复添加
    const isAlreadyAdded = this.state.favorites.some(item => item.imdbID === movie.imdbID);
    if (!isAlreadyAdded) {
      this.setState(prevState => ({
        favorites: [...prevState.favorites, movie]
      }));
    }
  };

  render() {
    return (
      <div className="app">
        {/* 假设这里是你的电影列表渲染,每个MovieItem传入addToFavorites方法和电影数据 */}
        <MovieItem 
          Title="你的电影标题" 
          Year="2024" 
          Poster="海报链接" 
          imdbID="tt1234567"
          addToFavorites={this.addToFavorites} 
        />
        {/* 把收藏列表传给Favorites组件 */}
        <Favorites movies={this.state.favorites} />
      </div>
    );
  }
}

export default App;

步骤2:修改MovieItem组件,调用父组件的添加方法

把按钮的点击事件从打印Title改成调用父组件传过来的addToFavorites方法,同时把当前电影的完整信息(包括imdbID、Title、Year)传过去,注意统一属性名的大小写(比如把Title改成title,和Favorites里的字段一致)。

// 修改后的MovieItem.js
import React, { Component } from 'react';
import './MovieItem.css';

class MovieItem extends Component {
  render() {
    const { Title, Year, Poster, imdbID, addToFavorites } = this.props;
    // 统一字段名大小写,方便后续处理
    const movieData = {
      imdbID,
      title: Title,
      year: parseInt(Year)
    };

    return (
      <article className="movie-item">
        <img className="movie-item__poster" src={Poster} alt={Title} />
        <div className="movie-item__info">
          <h3 className="movie-item__title">{Title}&nbsp;({Year})</h3>
          {/* 点击按钮时调用父组件的添加方法 */}
          <button 
            onClick={() => addToFavorites(movieData)} 
            type="button" 
            className="movie-item__add-button"
          >
            Добавить в список
          </button>
        </div>
      </article>
    );
  }
}

export default MovieItem;

步骤3:修改Favorites组件,接收父组件传递的收藏列表

现在Favorites不需要自己维护movies的state了,直接使用父组件传过来的props.movies,同时修正map时的key错误(原来用item.id,但我们的数据里是imdbID)。

// 修改后的Favorites.js
import React, { Component } from 'react';
import './Favorites.css';

class Favorites extends Component {
  render() {
    // 从props接收收藏列表
    const { movies } = this.props;

    return (
      <div className="favorites">
        <input value="Новый список" className="favorites__name" />
        <ul className="favorites__list">
          {movies.map((item) => {
            // 使用imdbID作为唯一key,避免警告
            return <li key={item.imdbID}>{item.title} ({item.year})</li>;
          })}
        </ul>
        <button type="button" className="favorites__save">Сохранить список</button>
      </div>
    );
  }
}

export default Favorites;

额外说明

  • 如果你的项目已经在使用Redux(代码里看到了import { store } from '../..'),也可以通过Redux的全局状态来管理收藏列表:在MovieItem里dispatch一个添加收藏的action,在Favorites里通过connect订阅store的收藏数据,这种方式适合更复杂的应用场景。
  • 我们添加了重复检查逻辑,避免同一部电影被多次添加到收藏列表里,你可以根据需求调整这个逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 21:44:07