alejandro
alejandro

Reputation: 409

React. How to show data loading message on API call

Trying to render an API call which returns an array of products.

How to show loading message on products render. (Currently the "loading" message is not being displayed)

useGetProducts.js

import { useEffect, useState } from "react";
import axios from "axios";

const useGetProducts = (API) => {
  const [products, setProducts] = useState(null);
  const [error, setError] = useState("");
  const [loaded, setLoaded] = useState(false);
  useEffect(() => {
    (async () => {
      try {
        async function fetchData() {
          const response = await axios(API);
          setProducts(response.data)
        }
        fetchData();
        
      } catch (error) {
        setError(error.message);
      } finally {
        setLoaded(true);
      }
    })();
  }, []);

  return { products, error, loaded };
};

export default useGetProducts

ProductList.js

import React from "react";
import ProductItem from "./ProductItem";
import useGetProducts from "../hooks/useGetProducts";
import { Link } from "react-router-dom";
import { API } from '../constants/constants';

const ProductList = () => {
  const data = useGetProducts(`${API}?limit=9&offset=0`);

  return (
    <section className="theme-section">
      {data.loaded ? 
        <>
        {data.products && data.products.map((product) => (
          <div key={product.id}>            
            <ProductItem product={product} />
            <Link to={`/product/${product.id}`}>ver detalle</Link>
            <br /><br />
            <hr />
          </div>
        ))}
        </>
        : "loading"
      }
      
    </section>
  )
}

export default ProductList;

Currently the message is not being displayed

Upvotes: 2

Views: 715

Answers (2)

Hritik Sharma
Hritik Sharma

Reputation: 2010

set your loaded state to false when you enter in fetchData function and in finally method, update loaded state to true.

useEffect(() => {
    (async () => {
      try {
        async function fetchData() {
          setLoaded(false);
          const response = await axios(API);
          setProducts(response.data);
        }
        fetchData();
        
      } catch (error) {
        setError(error.message);
      } finally {
        setLoaded(true);
      }
    })();
  }, []);

Upvotes: 1

Idrizi.A
Idrizi.A

Reputation: 12010

What is happening here is that you're calling fetchData without waiting for it, which is immediately setting loaded to true.

I don't think there is a need for the fetchData function here, so either remove it or await it:

const [products, setProducts] = useState(null);
const [error, setError] = useState("");
const [loaded, setLoaded] = useState(false);
useEffect(() => {
  (async () => {
      const response = await axios(API);
      setProducts(response.data)
    } catch (error) {
      setError(error.message);
    } finally {
      setLoaded(true);
    }
  })();
}, []);

Upvotes: 2

Related Questions