以下代碼的目標是將資料從 firebase 實時資料庫中提取到一個名為popularMovies 的陣列中。(實時資料庫中的資料量為 1000。)然后從該陣列中隨機選取一個索引,并將該索引處的電影資料顯示在頁面上。當用戶單擊喜歡的按鈕時,該電影資料將存盤在用戶 id 下的 firestore 檔案中,并選擇另一個隨機索引來顯示新電影。
下面的代碼大部分作業,但我注意到 console.log("run!") 在頁面加載和點擊喜歡的按鈕時執行 1000 次(正在讀取的資料的大小)。我希望了解為什么會出現這種情況,因為它在讀取資料的 forEach 回圈之外。
此外,當單擊該按鈕一次時,所有資料都會更新,但顯示不會反映更改。但是,再次單擊該按鈕確實會隨著顯示再次更新資料(正如我希望第一次發生的那樣)。這將繼續,按鈕僅在每隔一次按下后更新顯示。我也想知道是什么導致了這個錯誤。
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([]);
var [render, setRender] = React.useState(1);
console.log("run!");
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];
}
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;
uj5u.com熱心網友回復:
你看到的原因console.log()1000倍,是因為你的forEach()回圈更新的狀態變數(popularMovies)中定義RateMovies()。每次狀態改變時,React 都會重新渲染你的組件。
不要一次添加一個新專案,而是在forEach回圈中創建一個新陣列。這只會修改一次狀態,這意味著組件應該只重新渲染一次。
嘗試這樣的事情:
useEffect(() => {
popularMoviesRef.once("value").then(function(snapshot){
var newArray = []
snapshot.forEach(function(childSnapshot){
var key = childSnapshot.key;
var data = childSnapshot.val();
newArray.push({
key: key,
movieTitle: data.movie_title,
moviePoster: data.movie_poster,
movieYear: data.movie_year,
movieGenre: data.movie_genre,
movieRating: data.imdb_rating
})
});
setPopularMovies([...popularMovies, ...newArray])
}));
}, [render]);
至于你的按鈕沒有重新渲染你想要的資料,我不是 100% 肯定,但這可能與 JavaScript 處理承諾的方式有關。popularMoviesRef.once您的呼叫useEffect可能與您的db.collection('users').doc(user_id).update. 您可以通過向console.log()您的useEffect函式添加 a來測驗它,以嘗試查看它是否在"Successfully Updated!".
請參閱此處:JavaScript 承諾中的執行順序是什么?
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/345873.html
上一篇:如何在redux中獲取以前的狀態
