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状态即可实现相同效果,修改点如下:
- 新增state:
const [currentIndex, setCurrentIndex] = useState(Math.floor(Math.random() * (1000 + 1))) - 把原来的
index变量替换为currentIndex likedMovie函数中修改index的逻辑替换为:setCurrentIndex(Math.floor(Math.random() * (1000 + 1)))
内容的提问来源于stack exchange,提问作者Kris
相关产品推荐
相关产品推荐

