Search code examples
reactjsreduxmappingdestructuring

products is not a function after destructuring


I have my homepage where I received the products with the redux method but I did not want to render them on the home page so I did it with a single product component, but again I wanted to display the products in react-Alice-carousel I sent the products in the homepage through props and destrusctured it in the Single product and tried to create the items props of react-alice-carousel through jsx but got an error product.map is not a function.

My Single Product Component.

import React from "react";
import AliceCarousel from "react-alice-carousel";
// import { Button, Card, Container } from "react-bootstrap";
// import { FaShoppingCart } from "react-icons/fa";
// import { useDispatch, useSelector } from "react-redux";
import { Link } from "react-router-dom";
// import { AddToCartAction, RemoveFromCart } from "../../actions/cartActions";
import UICARD from "../../interface/UICARD";
// import classes from "./home.module.css";

export function numberWithComas(x) {
  return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}

const SingleProduct = ({ product }) => {

  const items = product.map((p) => {
    return (
      <Link to={`/product/${p._id}`}>
        <UICARD>
          <img src={p.image} alt={p.name} />
          <span>
            {p.name}
             <span>{p.description}</span>
          </span>

          <span>{p.price}</span>
        </UICARD>
      </Link>
    );
  });

  const responsive = {
    0: {
      items: 4,
    },
    512: {
      items: 6,
    },
  };
  return (
    <div>
      <AliceCarousel
        items={items}
        disableDotsControls
        infinite
        mouseTracking
        responsive={responsive}
      />
    </div>
  );
};

export default SingleProduct;

My Home Page

import React, { useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import { Products } from "../../actions/productsActions";
import ErrorMessage from "../../helpers/ErrorMessage";
import Loading from "../../helpers/Loading";
import SideBar from "../Home/SideBar";
import SingleProduct from "../Home/SingleProduct";
import classes from '../Home/home.module.css'

const Home = () => {

 

const dispatch = useDispatch();

const productList = useSelector((state) => state.productList);

const { products, error, loading } = productList

console.log(products);
useEffect(() => {
    dispatch(Products());
},[dispatch])

  return (
    <div className ={classes.home}>
      {error && <ErrorMessage variant={error.info?"info":"danger"}>{error}</ErrorMessage>}
      {loading && <Loading />}
      <SideBar />
      <div className={classes.productContainer}>
        {
          products.map((product) => {
            return <SingleProduct product={product} key={product._id} />
          })
        }
      </div>
    </div>
  );
};

export default Home;

Solution

  • You need to change you home compoent like that since singleProduct need to have a props peroduct as an array , i recommand to use prop-types to avoid this kind of problems

    import React, { useEffect } from "react";
    import { useDispatch, useSelector } from "react-redux";
    import { Products } from "../../actions/productsActions";
    import ErrorMessage from "../../helpers/ErrorMessage";
    import Loading from "../../helpers/Loading";
    import SideBar from "../Home/SideBar";
    import SingleProduct from "../Home/SingleProduct";
    import classes from '../Home/home.module.css'
    
    const Home = () => {
    
     
    
    const dispatch = useDispatch();
    
    const productList = useSelector((state) => state.productList);
    
    const { products, error, loading } = productList
    
    console.log(products);
    useEffect(() => {
        dispatch(Products());
    },[dispatch])
    
      return (
        <div className ={classes.home}>
          {error && <ErrorMessage variant={error.info?"info":"danger"}>{error}</ErrorMessage>}
          {loading && <Loading />}
          <SideBar />
          <div className={classes.productContainer}>
            <SingleProduct product={products} />
          </div>
        </div>
      );
    };
    
    export default Home;