-1

I fetched some data from my Mongo database which is returned as an object inside my useEffect hook function i.e.response in my code. I then declare a state myorders and wanted to set its value coming from the API.And finally. I wanted to map these data into different rows in my UI.

But the problem is when I try to setState in the component by passing the fetched orders in the setState() function, it returns an empty object. The console.log(state) shows an empty array.

code

import React, { useEffect, useState } from "react";
import { useRouter } from "next/router";

const Orders = () => {
  const router = useRouter();
  const [myorders, setMyorders] = useState();

  useEffect(() => {
    const fectOrders = async () => {

        let a = await fetch(`${process.env.NEXT_PUBLIC_HOST}/api/myorders`, {
          method: "POST", // or 'PUT'
          headers: {
            "Content-Type": "application/json",
          },
          body: JSON.stringify({ token: localStorage.getItem("token") }),
        });
        let response = await a.json();
        console.log("RES = ",response)
        setMyorders(response.myorders)
        console.log("MY = ",myorders)
      }

      if (!localStorage.getItem("token")) {
        router.push("/");
      } else {
        fectOrders();
      }
  }, []);

  

  return (
    <div className="container mx-auto">
      <h1 className="font-bold text-center text-2xl p-8">My Orders</h1>
      <div className="flex flex-col">
        <div className="overflow-x-auto sm:-mx-6 lg:-mx-8">
          <div className="py-2 inline-block min-w-full sm:px-6 lg:px-8">
            <div className="overflow-hidden">
              <table className="min-w-full border-[1px]">
                .
                .
                .
              </table>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
};



export default Orders;

ANd I got these values

err

As you can see that API is returning value but setState() is not working.

What To Do?

MagnusEffect
  • 3,363
  • 1
  • 16
  • 41
  • but even if I put setState() after fetcOrder(), idont get the values; – MagnusEffect Apr 30 '22 at 12:45
  • 2
    Your `console.log("MY = ",myorders)` cannot show you the fetched values, as `setMyorders()` *schedules* a new state for the next component re-render. When you call `console.log("MY = ",myorders)` the component has not been yet re-rendered, so the state you're logging is the *initial state* you set with `useState()` (`undefined`, in this case) – cheesyMan Apr 30 '22 at 12:47
  • @cheesyMan Yes you're right, I noticed that when I reloads it , the values do not set, but if I do any arbitrary change in the code (like adding space) and save the file, the value appears. But what is the solution for this? – MagnusEffect Apr 30 '22 at 12:52

1 Answers1

0

I had add myorders as dependency in useEffect which solves the problem,

So my useEffect is like this

  useEffect(() => {
    const fectOrders = async () => {

        let a = await fetch(`${process.env.NEXT_PUBLIC_HOST}/api/myorders`, {
          method: "POST", // or 'PUT'
          headers: {
            "Content-Type": "application/json",
          },
          body: JSON.stringify({ token: localStorage.getItem("token") }),
        });
        let response = await a.json();
        console.log("RES = ",response)
        //setMyorders(response.myorders)
        console.log("MY = ",myorders)
        return response.myorders;
      }

      if (!localStorage.getItem("token")) {
        router.push("/");
      } else {
        fectOrders().then((ord)=>setMyorders(ord)).catch((err)=>console.log(err));
      }
  }, [myorders]);
MagnusEffect
  • 3,363
  • 1
  • 16
  • 41
  • You shouldn't add myorders in dependency of useEffect. Bcoz everytime myorders state is updated fetchorders will be called. You only want to fetch the orders on component mount right? – Inder Apr 30 '22 at 12:56
  • 5
    The code you have added above will result in infinite renders. – Inder Apr 30 '22 at 12:57
  • SO what is the alternative way? – MagnusEffect Apr 30 '22 at 12:59
  • The code I added in my answer, should've worked, check this [Codesandbox](https://codesandbox.io/s/trusting-dawn-cmopd6?file=/src/App.js). I'm using json placeholder data – Inder Apr 30 '22 at 13:03