0

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>

2 Answers 2

1

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]);
Sign up to request clarification or add additional context in comments.

3 Comments

I am receiving undefined though when I log tempTasks it appears to be empty?
Sorry it's setTasks([...tempTasks, newData]); // But this
oh yes that was creating an object
1

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 };
  }));
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.