My useEffect()
function is retrieving data from firebase and only renders one <TaskItem/>
on the screen.
I pull the data and store it in temptasks in my state then that is rendered using map to display a component for each item.
There are five items in my backend firebase and using console log I can see they are all received but why is only the first one rendering. Re-rendering the page shows all 5.
useEffect(() => {
if(userId!=='' && id !== userId)
setId(userId);
if (id !== '') {
let counter = 0;
db.collection('users').doc(id).collection('tasks').onSnapshot((snapshot)=>{
const tempTasks = [];
snapshot.forEach(
doc => {
var newData = doc.data();
newData.id = doc.id;
tempTasks.push(newData);
setTasks(tempTasks);
}
)
setTasks(tempTasks);
});
}
},[id, userId]);
<View style={styles.tasks}>
{temptasks.map((task) => {
return (
<View style={{ margin: 4}}>
<TaskItem/>
</View>
);
})}
</View>
CodePudding user response:
There is no render because you update the state with the same array (it has the same reference). You have to return an enriched copy.
useEffect(() => {
if(userId!=='' && id !== userId)
setId(userId);
if (id !== '') {
let counter = 0;
db.collection('users').doc(id).collection('tasks').onSnapshot((snapshot)=>{
const tempTasks = [];
snapshot.forEach(
doc => {
var newData = doc.data();
newData.id = doc.id;
tempTasks.push(newData);
setTasks(tempTasks); // Not this
setTasks([...tempTasks, newData]); // But this
}
)
setTasks(tempTasks); // no effect
});
}
},[id, userId]);
CodePudding user response:
While Pierre's answer works perfectly fine, you can do the same with a lot less code by using the docs
array, and a spread (...
) operator:
db.collection('users').doc(id).collection('tasks').onSnapshot((snapshot)=>{
const tempTasks = snapshot.docs.map(doc => {
return { ...doc.data(), id: doc.id };
})
setTasks(tempTasks);
});
Or even shorter (although we might lose some readability in this step):
db.collection('users').doc(id).collection('tasks').onSnapshot((snapshot)=>{
setTasks(snapshot.docs.map(doc => {
return { ...doc.data(), id: doc.id };
}));
});