Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I correctly add data from multiple endpoints called inside useEffect to the state object using React Hooks and Context API?

I am making calls to firestore inside the fetchData function and then adding the received data to state object but the problem is the global state is overwritten by the last api call as seen in my console.log output:

console log output

Here's my code :

import React, { useState, useEffect } from 'react';

import { db } from './firebase';

export const StateContext = React.createContext();

export function ContextController({ children }) {
    const intialState = {
        projectList: [],
        blogList: [],
        count: 0
    };

    const [state, setState] = useState(intialState);

    useEffect(() => {
        fetchData();
    }, []);

    async function fetchData() {
        // get all projects
        db.collection('projects')
            .get()
            .then((querySnapshot) => {
                const data = querySnapshot.docs.map((doc) => doc.data());
                let sorted = [];

                // loop through each object and push to sorted array
                data.forEach((item) => {
                    sorted.push(item.body);
                });
                // reverse sort the projects
                sorted.sort(
                    (a, b) => parseInt(b.project_id) - parseFloat(a.project_id)
                );
                setState({
                    ...state,
                    projectList: sorted
                });
            });

        // get all blogs
        db.collection('blog')
            .get()
            .then((querySnapshot) => {
                const data = querySnapshot.docs.map((doc) => doc.data());
                setState({
                    ...state,
                    blogList: data
                });
            });
    }

    return (
        <StateContext.Provider value={[state, setState]}>
            {children}
        </StateContext.Provider>
    );
}

How do I correctly add data from both endpoints to the state object so that I can access it anywhere in my app?

like image 878
Cozy Avatar asked Mar 23 '26 19:03

Cozy


1 Answers

I think the issue is where you spread the old state into setState the state has gone stale. React does some performance enhancements around setState that will make code like this not work as expected.

One thing to try is using the setState callback.

setState((state) => ({
                ...state,
                projectList: sorted
            }));
like image 63
spirift Avatar answered Mar 26 '26 08:03

spirift