0

Here is my code:

import React, { useEffect, useState } from 'react';
import { getDocs, collection } from 'firebase/firestore';
import { db } from '../firebase-config';


const Home = () => {

    const [postList, setPostList] = useState([]);
    const postsCollectionRef = collection(db, "data");

    useEffect(() => {
        const getPosts = async () => {
            const data = await getDocs(postsCollectionRef);
            let postListArray = []
            data.forEach((doc) => {
                const post = { ...doc.data() }
                postListArray.push(post)
            });
            setPostList(postListArray)
        };
        getPosts();
        console.log(postList);
    }, []);


    return (
        <div>test</div>
    );
};

export default Home;

On loading, the console.log returned an empty array. The spooky thing is when i changed anything , for example

    return (
        <div>test_epic</div>
    );

The console.log shows that it is an array. Anyone has any idea as to why? Please refer to the screepcap as attached.

the first render on loading

I changed anything and components rerendered

1 Answers1

0

Setting state in react is asynchronous, so the data is loaded and the state is set but the console.log statement is executed before the setting state async operation is complete

To make it a bit more clear this is how it works step by step

  1. Component is rendered and postList is initialized with a value of []
  2. useEffect is triggered
  3. Data is fetched
  4. A call to set a new value of postList is placed using setPostList (key here is a call is placed not that the data is actually updated)
  5. You print console.log with a value from Step 1
  6. The call from Step 4 is complete and now the data is actually updated

Here is an article that explains it with examples

And here is another answer that explains this deeply

Vin_it
  • 186
  • 1
  • 5
  • the article recommended using useEffect. Is it useEffect is synchronous but useState is asynchronous? – Nooba Noobie Jul 03 '22 at 06:22
  • Yes, you should use `useEffect` and this behavior in your question is how it is supposed to work. This shouldn't affect your React app – Vin_it Jul 03 '22 at 06:27