Home > Blockchain >  how to setState for an array of fulfilled promises
how to setState for an array of fulfilled promises

Time:05-26

In my react app, I am retrieving some data from firebase , but when I try to store the items in my state it stores only the first item of the fulfilled promises ,

const HomePage = (props) => {
  const [events ,setEvents] = React.useState([])
const fetchGames=async()=>{
    const DB =await db.collection('game').get()

    DB.docs.forEach(item=>{
      setEvents([...events,item.data()])
      console.log(item.data()); // Here shows all the items that stored in my firebase collection
     })
    }
    
    useEffect(()=>
    {
      fetchGames()
    }, [])
return(
<div>
{
     events.map((event)=>
        (
          <div>
            {event.home_color}
          </div>

        )
        )
    }
</div>
)

Eventually the events state will display only one item , unlike in the console log which displayed all the items , how to fix this?

CodePudding user response:

React state is not synchronous. So updating state in a for loop does not guarantee every iteration you will get an updated state.

You can prepare the final object in the forEach & then update state once it has finished. Something like -

const fetchGames=async()=>{
    const DB =await db.collection('game').get()
    const eventsFromDb = [];
    DB.docs.forEach(item=>{
      // update eventsFromDb array here 
    })
    // set state here
    setEvents(eventsFromDb);
}

CodePudding user response:

Repeatedly calling setEvents in your forEach loop does not allow for the state to actually be updated because the React useState hook is not synchronous.

You could do something like this:

setEvents([ ...events, ...DB.docs.map(item => item.data())])

Assuming the data() method isn't async - sorry I don't know Firebase.

CodePudding user response:

Because of setState is asynchronous.
Basically you can manage data from DB.docs.
After that you'll easily set state.

// Example

const collectData = DB.docs.map((item) => item.data());

// So .. your method like be

const fetchGames = async () => {
  const DB = await db.collection("game").get();

  const collectData = DB.docs.map((item) => item.data());

  setEvents([...events, ...collectData]);
};
  • Related