Search code examples
reactjsaxiosuse-effectuse-state

What is wrong with my useEffect()? It return empty object


I'm trying to fetch data from my server, I've tested the data fetching using Postman, everything is fine. I also double checked whether my API path was wrong, also not the issue.

I changed useEffect to useLayoutEffect, also no luck. I created a separate function outside the useEffect hook, also not working. I created console.log("I was here") on every single line, where each log was successfully printed inside the fetchProduct function.

Now I'm so stuck. I suspect the effects finish before the promise returns. Thank you in advance.

ProductDetail component

import React, { useEffect, useState } from "react"
import EcommerceLayoutsTypeFourteenth from "../layouts/Ecommerce/EcommerceLayoutsTypeFourteenth/EcommerceLayoutsTypeFourteenth"
import EcommerceLayoutsTypeSecond from "../layouts/Ecommerce/EcommerceLayoutsTypeSecond/EcommerceLayoutsTypeSecond"
import axios from "axios"

const ProductDetail = ({ match, products }) => {
  const [product, setProduct] = useState({})

  useEffect(() => {
    const fetchProduct = async () => {
      const response = await axios.get(`/api/products/${match.params.id}`)
      setProduct(response.data)
    }
    fetchProduct()
  }, [match])

  return (
    <>
      <EcommerceLayoutsTypeSecond product={product} />
      <EcommerceLayoutsTypeFourteenth products={products} />
    </>
  )
}

export default ProductDetail

This is my App.js

import React, { useState, useEffect } from "react"

import { BrowserRouter as Router, Route, Switch } from "react-router-dom"
import Container from "reactstrap/lib/Container"
import FootersLayoutsTypeEighth from "./layouts/FootersLayouts/FootersLayoutsTypeEighth/FootersLayoutsTypeEighth"
import Header from "./layouts/HeaderLayouts/Header.js"
import HomeScreen from "./screens/HomeScreen"
import ProductDetail from "./screens/ProductDetail"
import axios from "axios"

const App = () => {
  const [products, setProducts] = useState([])

  useEffect(() => {
    const fetchProducts = async () => {
      const response = await axios.get("/api/products/")
      setProducts(response.data)
    }
    fetchProducts()
  }, [])

  return (
    <Router>
      <Container>
        <Header dark={false} />
      </Container>
      <Switch>
        <Route
          exact
          path="/"
          render={(props) => <HomeScreen {...props} products={products} />}
        />
        <Route
          path="/products/:id"
          render={(props) => <ProductDetail {...props} products={products} />}
        />
      </Switch>
      <FootersLayoutsTypeEighth />
    </Router>
  )
}

export default App

Solution

  • Inside the object got and array for category, it look like this..

        const products = [{
        _id: 1,
        title: "GP Base Coat",
        description:
          "FLINKEN® Based Coat mortar is produced according to the requirement of BS EN 998-1; incorporating standardized binder, well graded silica sand, water retention ability additve for all types of brick and block rendering.",
        price: "40.00",
        poster: "./image/flinken-product-01.png",
        category: "gp-series",
        link: "/products/1",
        features: [
          "feature 1",
          "feature 2",
          "feature 3",
          "feature 4",
          "feature 5",
          "feature 6",
        ],
        rating: 4.5,
      },...]
    

    So every-time i call the products.features[0] the data inside my products state will become empty object.. so the solution here i just create state for features and products separately..

      const [product, setProduct] = useState({})
      const [feature, setFeature] = useState([])
    
      useEffect(() => {
        const fetchData = async () => {
          const { data } = await axios.get(`/api/products/${id}`)
          setFeature(data.features)
          setProduct(data)
        }
        fetchData()
      }, [id])
    

    thank you to all of you that contribute your time and effort to help me last week, i really appreciate all of you!