1

Here Below my code I would like to retrieve all data before starting the render of my component, is there any way to do that in react ? I guess it's maybe a simple code line but as I'm new in coding I still don't know all react components behavior. Thanks for your answer.

import { useState, useEffect } from "react";
import axios from "axios";
import Cookies from "js-cookie";
// import material ui
import CircularProgress from "@mui/material/CircularProgress";
import Box from "@mui/material/Box";
// import config file
import { SERVER_URL } from "../../configEnv";

const Products = ({ catList }) => {
  // catList is data coming from app.js file in format Array[objects...]
  console.log("catList ==>", catList);
  const [isLoading, setIsLoading] = useState(true);
  const [dataSku, setDataSku] = useState([]);

  console.log("datasku ==>", dataSku);

  const tab = [];
  useEffect(() => {
    // Based on the catList tab I fetch additionnal data linked with each object of catList array
    catList.slice(0, 2).forEach(async (element) => {
      const { data } = await axios.post(`${SERVER_URL}/products`, {
        product_skus: element.product_skus,
      });

      // The result I receive from the call is an array of objects that I push inside the Tab variable
      tab.push({ name: element.name, content: data });
      setDataSku(tab);
      console.log("tab ==>", tab);
      setIsLoading(false);
    });
  }, [catList]);

  return isLoading ? (
    <Box sx={{ display: "flex" }}>
      {console.log("there")}
      <CircularProgress />
    </Box>
  ) : (
    <div className="products-container">
      <div>LEFT BAR</div>
      <div>
        {dataSku.map((elem) => {
          return (
            <div>
              <h2>{elem.name}</h2>
            </div>
          );
        })}
      </div>
    </div>
  );
};

export default Products; ```
4
  • You need an empty dependency array in your useEffect() hook if you just fetch your data once. Commented Dec 15, 2021 at 0:06
  • Thanks for your answer but by removing the dependency of catList, the useEffect content is not being trigged Commented Dec 15, 2021 at 0:13
  • Is there a chance you could change the api to be able to fetch them all in one request? Doing a for loop of async api calls isn't exactly best practice as it introduces multiple points of failure and increases network traffic Commented Dec 15, 2021 at 1:07
  • Unfortunately I do not have the hand on api 😞 so I have to make a call for each cat = category request Commented Dec 15, 2021 at 9:28

2 Answers 2

1

@Jessy use your loading state to fetch data once,

In your useEffect, check for loading,

useEffect(() => {
  if(loading) {
    catList.slice(0, 2).forEach(async (element) => {
      const { data } = await axios.post(`${SERVER_URL}/products`, {
        product_skus: element.product_skus,
      });
      tab.push({ name: element.name, content: data });
      setDataSku(tab);
      console.log("tab ==>", tab);
      setIsLoading(false);
    });
   }
  }, [catList]);`
Sign up to request clarification or add additional context in comments.

1 Comment

Many Thanks for the answer, but when I had this isLoading condition seems to be a bit better but not all data are called (normally 223 called should be done ) the result displayed in my html are random sometime only 1 data some time 5 sometime 8 ... but not 223 results are displayed at every page refresh. But from my console I can see that I have the results of all 223 request stored in the variable tab
0

I finally managed to displayed all results by adding this condition on the isLoading

if (tab.length === catList.length) {
          setIsLoading(false);
        }

Many thanks guys for your insight :)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.