Home > Net >  Map function not running after useEffect sets the state to a non-empty list
Map function not running after useEffect sets the state to a non-empty list

Time:05-18

I am trying to fetch some data from my node js server that returns to me an array. Upon receiving this array, I want to map through it and display several iterations of the same component with this data. However, the map function does not run as the initial state value I set was an empty array. My question is, why isn't the map function running after the state is changed in the useEffect function? Here is the code:

const [groupData, setGroupData] = useState([]);

useEffect(() => {
    const func = async () => {
        const fetchData = await fetch("http://localhost:5000/api/get-groups", {
            method: "GET",
            credentials: "include",
            headers: {
                "Content-Type": 'application/json',
                'Access-Control-Allow-Methods': 'GET,PUT,POST,DELETE,PATCH,OPTIONS'
            }
        })

        const jsonFetch = await fetchData.json();
        setGroupData(jsonFetch.groupData);
    }

    func();
}, [])

return (
    {groupData.map((elem) => {
        <Card data={elem} />
    })}
)

But the cards are simply not visible. I can console.log to see the data coming into the react act as expected. I also tried changing the second parameter of the useEffect function to [groupData] instead of []. But it still does not work. Any help would be appreciated. Thank you!

CodePudding user response:

It seems you didn't return anything from .map() method. Try to do this (remove braces):

return (
    {groupData.map((elem) => <Card data={elem} /> )}
)

Also it's recommended to add uniq keys when you render a list (https://reactjs.org/docs/lists-and-keys.html)

CodePudding user response:

When you use async functions, you must continue your logic only when requested content is delivered. You must implement then function, as in the example bellow:

const [groupData, setGroupData] = useState([]);

useEffect(() => {
    const func = async () => {
        fetch("http://localhost:5000/api/get-groups", {
            method: "GET",
            credentials: "include",
            headers: {
                "Content-Type": 'application/json',
                'Access-Control-Allow-Methods': 'GET,PUT,POST,DELETE,PATCH,OPTIONS'
            }
        }).then(response => {
           setGroupData(response.json().groupData);
        }).catch(e => {
            // Ops, there's a problem...
        });
    }
    func();
}, [])

return (
    {groupData.map((elem) => {
        <Card data={elem} />
    })}
)

[]s

CodePudding user response:

Because groupData don't have yet data when component render. Try this below code:

const [groupData, setGroupData] = useState([]);

useEffect(() => {
    const func = async () => {
       try{
           const fetchData = await fetch("http://localhost:5000/api/get-groups", {
            method: "GET",
            credentials: "include",
            headers: {
                "Content-Type": 'application/json',
                'Access-Control-Allow-Methods': 'GET,PUT,POST,DELETE,PATCH,OPTIONS'
            }
        })

        const jsonFetch = await fetchData.json();
        setGroupData(jsonFetch.groupData);
        } catch (err){console.log(err)}; //<== Add try...catch to avoid app crash and catch error!          
    }

    func();
}, [])

return (
    {groupData?.map((elem, index) => {
        <Card key={index} data={elem} />
    })} //<== add "?" after groupData and key attribute in <Card /> !
)
  • Related