I am trying to retrieve Game names from firestore and display in a list on the page. For this I am using a component GameList(to display the names retrieved) and Home(to fetch and pass the retrieved data to GameList component).
Here is my code : Home.js :-
import { useState, useEffect } from 'react';
import { personalDatabaseFirestore } from '../firebase/personalConfig';
import GameList from './GameList';
import './Home.css'
export default function Home(){
const [data, setData] = useState(null);
useEffect(()=>{
const ref = personalDatabaseFirestore.collection('Games');
let results = []
const unsub = ref.onSnapshot((snapshot)=>{
snapshot.docs.forEach((doc) => {
results.push({...doc.data(), id: doc.id});
})
},(error)=>{
console.log(error);
})
setData(results);
return ()=>unsub();
},[]);
console.log(data);
return (
<div className='mainpage-container'>
{data && <GameList games={data}/>}
</div>
);
}
GameList.js :-
export default function GameList({games}){
console.log('game list recieved\n', games);
return (
<ul>
{
games.map((doc)=>{
return (<li key={doc.id}>{doc.name}</li>);
})
}
</ul>
)
}
Console screenshot shows that i am able to retrieve the data successfully from firestore and am able to pass it to GameList component too . But then after logging out the information in gameList component it is not rendering the list that it is supposed to return.
CodePudding user response:
The onSnapshot()
returns data asynchronously so you should use setData
within it. That'll also ensure any data updates received later are also rendered. Try refactoring the code as shown below:
useEffect(() => {
const ref = personalDatabaseFirestore.collection('Games');
const unsub = ref.onSnapshot((snapshot) => {
const results = snapshot.docs.map((doc) => ({ id: doc.id, ...doc.data() }))
setData(results);
})
return () => unsub();
}, []);
If you need to fetch data only once, then I'd recommend using get()
instead of onSnapshot
:
useEffect(() => {
const ref = personalDatabaseFirestore.collection('Games');
const fetchData = async () => {
const snapshot = await ref.get();
const results = snapshot.docs.map((doc) => ({
id: doc.id,
...doc.data()
}))
setData(results);
}
fetchData();
}, []);