英文:
How can I load my data before the component is loaded?
问题
以下是您要翻译的代码部分:
import Navbar from '../../components/navbar/navbar'
import './playlist.css'
import { useEffect, useState } from 'react'
import album from '../../assets/album1.jpeg'
import { collection, getDocs, query, where } from 'firebase/firestore'
import { db, storage } from '../../config/firebase'
import { getDownloadURL, ref } from "firebase/storage";
import { useNavigate, useParams } from 'react-router'
import SongDetail from '../../components/song-detail/songDetail'
function Playlist() {
const navigate = useNavigate();
const { id } = useParams()
const [dataBase, setDataBase] = useState()
const [songDB, setSongDB] = useState([])
const [count, setCount] = useState(0)
const [Url, setUrl] = useState()
useEffect(() => {
const PlaylistCollectionRef = collection(db, "playlist")
const fetchData = async () => {
try {
const q = query(PlaylistCollectionRef, where("PlaylistId", "==", id))
const data = await getDocs(q)
const filteredData = data.docs.map((doc) => ({ ...doc.data(), id: doc.id }))
setDataBase(filteredData)
if (filteredData) {
filteredData[0].Songs.map((data, i) => performDownload(data))
console.log("FILTER", filteredData)
}
} catch (error) {
console.log(error)
}
}
fetchData()
}, [count])
const performDownload = async (songID) => {
const SongCollectionRef = collection(db, "music")
const q = query(SongCollectionRef, where("SongId", "==", songID))
const data = await getDocs(q)
const filteredData1 = data.docs.map((doc) => ({ ...doc.data(), id: doc.id }))
songDB.push({
filteredData1
})
console.log("SONG DB", songDB)
console.log("SONG NAME", songDB[0]?.filteredData1[0].SongName)
}
return (
<div className="playlist-wrapper" id='playlist-id'>
<div className="playlist-navbar">
<Navbar />
</div>
<div className="playlist-main">
<div className="playlist-main-section-1">
<div className="playlist-main-section-1-subsection">
<div className="playlist-section-1-back">
<button>BACK</button>
</div>
<div className="playlist-section-1-front">
<div className="playlist-subsection-images">
<div className="playlist-img-box">
<img src={album} alt="" />
</div>
</div>
<div className="playlist-subsection-controls">
<div className="playlist-subsection-controls-name">
<h1>MY PLAYLIST</h1>
</div>
<div className="playlist-subsection-controls-control">
<button>Play</button>
<button>Add</button>
</div>
</div>
</div>
</div>
</div>
<div className="playlist-main-section-2">
<div className="playlist-playlist-subsection">
{
dataBase ?
dataBase[0].Songs.map((data, i) =>
<SongDetail
playlistId={id}
albumId={data.albumId}
num={i + 1}
name={songDB[i * 2]?.filteredData1[0].SongName}
/>
)
: "LOADING"
}
</div>
</div>
</div>
</div>
)
}
export default Playlist
希望这对您有所帮助!
英文:
I am getting the data from the firebase database but am unable to show the data as the component is being executed first and then the data is being load. How can I fix this the proper way? The data loading part is working completely fine just that my map function is loading first and the data is loading after so it isn't being displayed.
import Navbar from '../../components/navbar/navbar'
import './playlist.css'
import {useEffect, useState } from 'react'
import album from '../../assets/album1.jpeg'
import { collection, getDocs ,query, where} from 'firebase/firestore'
import { db ,storage} from '../../config/firebase'
import { getDownloadURL, ref } from "firebase/storage";
import { useNavigate,useParams } from 'react-router'
import SongDetail from '../../components/song-detail/songDetail'
function Playlist(){
const navigate = useNavigate();
const {id} = useParams()
const [dataBase, setDataBase]=useState()
const [songDB,setSongDB] = useState([])
const [count,setCount] =useState(0)
// var dataBase = [1,2,3,4,5,6,7]
const [Url,setUrl] = useState()
useEffect(()=>{
const PlaylistCollectionRef = collection(db, "playlist")
const fetchData = async ()=>{
try{
const q = query(PlaylistCollectionRef, where("PlaylistId", "==", id))
const data = await getDocs(q)
// const data = await getDocs(PlaylistCollectionRef)
const filteredData = data.docs.map((doc)=>({...doc.data(), id:doc.id}))
setDataBase(filteredData)
if(filteredData){
filteredData[0].Songs.map((data,i)=> performDownload(data) )
console.log("FILTER",filteredData)
}
// handleDownload(filteredData[0].albumUrl)
}catch(error){
console.log(error)
}
}
fetchData()
},[count])
// const downloadSongData = async()=>{
// if(dataBase?.length > 0){
// console.log("DB :: ",dataBase)
// dataBase[0].Songs.map((data,i)=> performDownload(data) )
// console.log(dataBase[0]?.Songs)
// }
// }
const performDownload = async(songID)=>{
const SongCollectionRef = collection(db, "music")
const q = query(SongCollectionRef, where("SongId", "==", songID))
const data = await getDocs(q)
// const data = await getDocs(PlaylistCollectionRef)
const filteredData1 = data.docs.map((doc)=>({...doc.data(), id:doc.id}))
songDB.push({
filteredData1
})
console.log("SONG DB",songDB)
console.log("SONG NAME",songDB[0]?.filteredData1[0].SongName)
}
return(
<div className="playlist-wrapper" id='playlist-id'>
<div className="playlist-navbar">
<Navbar/>
</div>
<div className="playlist-main">
<div className="playlist-main-section-1">
<div className="playlist-main-section-1-subsection">
<div className="playlist-section-1-back">
<button>BACK</button>
</div>
<div className="playlist-section-1-front">
<div className="playlist-subsection-images">
<div className="playlist-img-box">
<img src={album} alt="" />
</div>
</div>
<div className="playlist-subsection-controls">
<div className="playlist-subsection-controls-name">
<h1>MY PLAYLIST</h1>
</div>
<div className="playlist-subsection-controls-control">
<button>Play</button>
<button>Add</button>
</div>
</div>
</div>
</div>
</div>
<div className="playlist-main-section-2">
<div className="playlist-playlist-subsection">
{
dataBase ?
dataBase[0].Songs.map((data,i)=>
<SongDetail
playlistId = {id}
albumId = {data.albumId}
num = {i+1}
name = {songDB[i*2]?.filteredData1[0].SongName}
/>
)
: "LOADING"
}
</div>
</div>
</div>
</div>
)
}
export default Playlist
答案1
得分: 0
一旦您进入setDataBase()
设置函数,您的组件应该使用新的状态值重新渲染,您确定在data.docs
上进行映射后是否获得了正确的结果?
导致问题的第二个可能原因是,在performDownload()
函数中,您直接通过将筛选后的结果推送到songDB状态来修改状态,这个操作的结果不会在应用程序UI中可见,您应该使用setSongDB
设置器来使您的数据完全响应式。
回答这个问题 - 为了在浏览器输出屏幕之前加载数据,您可以使用useLayoutEffect钩子:https://react.dev/reference/react/useLayoutEffect,但我认为在您的情况下这并不是必要的。检查您的数据获取的结果是否是正确/已等待的格式,然后使用状态设置器来更新状态。
英文:
Once you go to setDataBase()
setter function, your component should re-render with a new state value, are you sure that you are getting the right results after mapping on data.docs
?
The second thing that can cause your problem is that in performDownload()
function you are modifying the state directly by pushing filtered results to the songDB state and the results of this operation will be not visible in the app UI, you should use setSongDB
setter to make your data fully reactive.
Answering the question- in order to load your data before browser prints out the screen you can use useLayoutEffect hook: <https://react.dev/reference/react/useLayoutEffect>, but I think it's not necessary in your case. Check the results of your data fetching if they are in correct/awaited format and then use state setters to update a state.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论