surjendu_dey
surjendu_dey

Reputation: 588

dynamically slice array of product data to display in ReactJs component

I'm building an ecommerce store with Reactjs where I need to display the products in home component dynamically. Now in the home component the products should follow some styling like for example 4 products in first row, 1 in second row, 3 in the next row etc. I'm calling all the product data array from the database as products and passing them in another component called Products component by mapping through the products array. But in doing so I'm using slice() method and hard coding how many and which products should pass in the in each rows. Is there a way instead of hardcoding number of products per row like Array.slice(0,4) I can achieve the same styling in a more dynamic way

import React, { useState, useEffect } from "react";
import "./Home.css";
import Product from "./Product";
import { db } from "./firebase";

function Home() {
  const [products, setProducts] = useState([]);

  useEffect(() => {
    db.collection("products").onSnapshot((snapshot) => {
      setProducts(
        snapshot.docs.map((doc) => ({ id: doc.id, products: doc.data() }))
      );
    });

return (
    <div className="home">
        <div className="home__container">

          <div className="home__row">
                 {products.slice(0, 4).map(({ id, products }) => (      //Hard coding number of products
            <Product 
              key={id}
              title={products.title}
              price={products.price}
              image={products.image}
              rating={products.rating}
            />
          ))}
        </div>

          <div className="home__row">

              {products.slice(4).map(({ id, products }) => (            //Hard coding number of products
            <Product
              key={id}
              title={products.title}
              price={products.price}
              image={products.image}
              rating={products.rating}
            />
          ))}
        </div>

          <div className="home__row">
                {products.slice(5, 10).map(({ id, products }) => (      //Hard coding number of products
            <Product
              key={id}
              title={products.title}
              price={products.price}
              image={products.image}
              rating={products.rating}
            />
          ))}
        </div>

Upvotes: 1

Views: 1472

Answers (2)

Nhut Dinh Ba
Nhut Dinh Ba

Reputation: 354

Actually you can achieve the same thing with CSS. Set display: flex for parent div and flex: 0 25% for each product item:

<div style={{style: "display: flex"}}>
  {

    products.map((product, index)=>{
      <div style={{flex: "0 25%"}}>
        <Product 
              key={id}
              title={product.title}
              price={product.price}
              image={product.image}
              rating={product.rating}
            />
      </div>  
    })
  }
</div>

But in case you still prefer your current approach then I can suggest this solution:

{
  const productWithRows = products.reduce((memo, product, index)=>{
    memo[Math.floor(index/4] = product;
    return memo;
  },[])

  productWithRows.map((productsPerRow, index)=> {
    <div className="home__row">   
      {productsPerRow.map((product)=>{

        <Product 
          key={id}
          title={product.title}
          price={product.price}
          image={product.image}
          rating={product.rating}
        />
      })}
  </div>
 })
}

Upvotes: 1

Kid
Kid

Reputation: 1240

follow some styling like for example 4 products in first row, 1 in second row, 3 in the next row etc.

This makes you do hard-coding, if you want to avoid this, you should pass those numbers(rules) via props or fetch from database.

Upvotes: 0

Related Questions