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

React电影评分组件点击喜欢不更新 如何转为类组件触发重渲染?

问题根因

你当前点击喜欢按钮后页面不更新,核心原因是index、movie都属于组件内部的普通局部变量,React不会监听这类变量的变更,只有state或props发生变化时才会触发组件重新渲染,执行render/return中的更新逻辑。

类组件转换实现

以下是转换后的完整类组件代码,点击喜欢按钮后修改state即可自动触发render方法重新执行,更新页面内容:

import React, { Component } from 'react';
import './App.css';
import firebase from 'firebase/compat/app';
import 'firebase/database';
import 'firebase/firestore';

class RateMovies extends Component {
  constructor(props) {
    super(props);
    this.popularMoviesRef = firebase.database().ref("/popular_movies");
    // 把需要触发更新的变量放到state中
    this.state = {
      popularMovies: [],
      currentIndex: Math.floor(Math.random() * (1000 + 1))
    };
    this.auth = firebase.auth();
    this.db = firebase.firestore();
    this.user_id = this.auth.currentUser.uid;
    // 绑定方法的this指向
    this.likedMovie = this.likedMovie.bind(this);
  }

  componentDidMount() {
    // 替代原函数组件的useEffect逻辑,组件挂载完成后拉取电影列表
    this.popularMoviesRef.once("value", (snapshot) => {
      const movies = [];
      snapshot.forEach((childSnapshot) => {
        const key = childSnapshot.key;
        const data = childSnapshot.val();
        movies.push({
          key: key, 
          movieTitle: data.movie_title, 
          moviePoster: data.movie_poster, 
          movieYear: data.movie_year,
          movieGenre: data.movie_genre, 
          movieRating: data.imdb_rating
        });
      });
      // 批量更新state,避免多次重复渲染
      this.setState({ popularMovies: movies });
    });
  }

  likedMovie() {
    const movie = this.state.popularMovies[this.state.currentIndex];
    this.db.collection('users').doc(this.user_id).update({
      "Rated.liked": firebase.firestore.FieldValue.arrayUnion({
        key: movie.key, 
        movieTitle: movie.movieTitle, 
        moviePoster: movie.moviePoster, 
        movieYear: movie.movieYear,
        movieGenre: movie.movieGenre, 
        movieRating: movie.movieRating,
      }),
    }).then(() => {
      console.log("Successfully updated!");
      // 修改state触发render重渲染
      this.setState({
        currentIndex: Math.floor(Math.random() * (1000 + 1))
      });
    });
  }

  render() {
    const movie = this.state.popularMovies[this.state.currentIndex];
    return (
      <div>
        <p>Rate Movies Here</p>
        <div> {movie?.movieTitle} </div>
        <div> {movie?.movieYear} </div>
        <br/>
        <button onClick={this.likedMovie}> Like</button>
        <button> Dislike</button>
        <br/>
        <br/>
        {/* 修正原代码中class属性的问题,React中需使用className */}
        <img className="rate-image" src = {`${movie?.moviePoster}`} alt="电影海报"/>
      </div>
    )
  }
}

export default RateMovies;

可选优化:无需转类组件的函数组件修改方案

如果你不想重构为类组件,只需要给原函数组件新增一个currentIndex状态即可实现相同效果,修改点如下:

  1. 新增state:const [currentIndex, setCurrentIndex] = useState(Math.floor(Math.random() * (1000 + 1)))
  2. 把原来的index变量替换为currentIndex
  3. likedMovie函数中修改index的逻辑替换为:setCurrentIndex(Math.floor(Math.random() * (1000 + 1)))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 16:57:00