【问题标题】:How do I convert this function into a class component so that I can use render to call the return?如何将此函数转换为类组件,以便我可以使用渲染调用返回?
【发布时间】:2023-03-31 03:51:01
【问题描述】:

以下代码的目标是将数据从移动对象导入到用户 id 下的 firestore 数据库中。一切正常,除了当我点击喜欢的按钮时,显示没有更新。我从 console.log 语句中知道,当按下 like 按钮时,会从数组中正确选择不同的电影(使用随机索引变量),但实际的标题和封面不会随着参考电影的变化而更新。

如何更改代码,以便在我按下喜欢的按钮后再次执行返回语句并更新显示?

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

function RateMovies() {

    const popularMoviesRef = firebase.database().ref("/popular_movies");
    const [popularMovies, setPopularMovies] = React.useState([]);

    useEffect(() => {
        
        popularMoviesRef.once("value", function(snapshot){

            snapshot.forEach(function(childSnapshot){
                var key = childSnapshot.key;
                var data = childSnapshot.val();

                setPopularMovies(currMovies => [...currMovies, { 
                    key: key, 
                    movieTitle: data.movie_title, 
                    moviePoster: data.movie_poster, 
                    movieYear: data.movie_year,
                    movieGenre: data.movie_genre, 
                    movieRating: data.imdb_rating
                }])
            });
        });
    }, []);

    var index = Math.floor(Math.random() * (1000 + 1));
    var movie = popularMovies[index];

    const auth = firebase.auth();
    var db = firebase.firestore();
    var user_id = auth.currentUser.uid;

    function likedMovie() {

        db.collection('users').doc(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(function(){
            console.log("Successfully updated!");
        });

        index = Math.floor(Math.random() * (1000 + 1));
        movie = popularMovies[index];
    }


    return (
        <div>
            <p>Rate Movies Here</p>
            <div> {movie?.movieTitle} </div>
            <div> {movie?.movieYear} </div>
            <br/>
            <button onClick={likedMovie}> Like</button>
            <button> Disike</button>
            <br/>
            <br/>
            <img class="rate-image" src = {`${movie?.moviePoster}`} />
            
        </div>
    )
  
  } 

  export default RateMovies;

【问题讨论】:

  • 更新后需要再次调用setPopularMovies,渲染会自动触发

标签: reactjs firebase render


【解决方案1】:

不是最好的解决方案,而是一种解决方法

 const [render, setRender] = React.useState(1);

    useEffect(() => {
        
        popularMoviesRef.once("value", function(snapshot){

            snapshot.forEach(function(childSnapshot){
                var key = childSnapshot.key;
                var data = childSnapshot.val();

                setPopularMovies(currMovies => [...currMovies, { 
                    key: key, 
                    movieTitle: data.movie_title, 
                    moviePoster: data.movie_poster, 
                    movieYear: data.movie_year,
                    movieGenre: data.movie_genre, 
                    movieRating: data.imdb_rating
                }])
            });
        });
    }, [render]);

    var index = Math.floor(Math.random() * (1000 + 1));
    var movie = popularMovies[index];

    const auth = firebase.auth();
    var db = firebase.firestore();
    var user_id = auth.currentUser.uid;

    function likedMovie() {

        db.collection('users').doc(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(function(){
            console.log("Successfully updated!");
            setRender(render++)
        });

        index = Math.floor(Math.random() * (1000 + 1));
        movie = popularMovies[index];
    }

【讨论】:

  • 这是可行的,但它有点慢。你知道为什么整个函数每次渲染都会运行 1000 次(popularMoviesRef 数据库的大小)吗?
  • @Kris 您是在谈论重新渲染或 firebase 查询负载吗?请纠正您的问题
  • 我不确定,但如果我将 console.log 放在 useEffect() 上方的行上,它会在页面加载和每次按下按钮时执行 1000 次。此外,我刚刚意识到必须按两次按钮才能更新显示。因此,如果数组最初位于索引 1,则按下按钮会将其更新为索引 2,但显示不会改变。然后当我再次按下按钮时,它会更新为索引 3,并且显示更改为显示索引 3 的信息(但我从未看到显示索引 2 的信息)。
【解决方案2】:

如果你想使用函数组件,只需摆脱 render 方法并保持这样:

    return (
        <div>
            <p>Rate Movies Here</p>
            <button onClick={likedMovie}> Like</button>
        </div>
    );

【讨论】:

  • 我正试图朝相反的方向前进。它以前是一个函数,但我希望能够使用渲染
  • 这是为什么呢?您可以使用推荐的功能组件来做任何事情
  • 好的,那么如何在按下按钮后执行return语句,以便在不使用渲染的情况下更新显示?
  • 请为您的问题添加更多上下文,以便我们提供帮助。
  • @abhipatil 我已经更新了我的问题以完全反映我的问题
猜你喜欢
  • 1970-01-01
  • 2012-12-01
  • 2021-07-02
  • 1970-01-01
  • 2012-04-20
  • 1970-01-01
  • 2021-07-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多