Home > Mobile >  How do I render a Company after 5 Products? | React js
How do I render a Company after 5 Products? | React js

Time:01-06

I'm trying to make a ecommerce store and I want to render a <CompanyCard/> component after every 2 <ProductCard/> components. I've never done anything like this so I'm not sure if I'm doing the right approach

Here is a example of what I want:

<ProductCard/>
<ProductCard/>
<CompanyCard/>
<ProductCard/>
<ProductCard/>
<CompanyCard/>
(and so on..)

but for some reason im getting a blank page with these 2 errors in the console

The above error occurred in the <CompanyCard> component:
Uncaught TypeError: Cannot read properties of undefined (reading '_id')

This is my code (I'm also using React Redux)

function HomePage() {
  let counter = 0;

  const dispatch = useDispatch();

  const productList = useSelector((state) => state.productList);
  const { error, loading, products } = productList;

  const companyList = useSelector((state) => state.companyList);
  const { companies } = companyList;

  useEffect(() => {
    dispatch(listProducts(), listCompanies());
  }, [dispatch]);

  return (
    <>
      <Navbar />
      <div className="homePage">
        <div className="centerItemsContainer">
          <div className="productsContainer">
            {products.map((product) => {
              counter  ;

              if (counter % 4 === 0) {
                const companyIndex = counter / 4 - 1;
                const company = companies[companyIndex];

                return (
                  <>
                    <CompanyCard company={company} />
                    <ProductCard product={product} />
                  </>
                );
              } else {
                return <ProductCard product={product} />;
              }
            })}
          </div>
        </div>
      </div>
      <Footer />
    </>
  );
}

export default HomePage;

CodePudding user response:

First, it seems like you are simply selecting a company that does not exist. Log companyIndex and see what values you are using.

Also, there is no need to manual keep track of counter, it is the second argument from map, so just write:

        {products.map((product, counter) => {

CodePudding user response:

I hope this helps if u want to render company on 4 th place pls change it to 4 same goes for what place u want

   const products = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
export const App = () => {
  return (
    <>
      {products.map((product, index) => {
        const counter = index   1;
        if (counter % 2 === 0) {
          return (
            <>
              <p>Prod{index}</p>
              <p>Company</p>
            </>
          );
        }
        return <p>Prod{index}</p>;
      })}
    </>
  );
};

CodePudding user response:

You are getting an error, because your iterator exceeds array length

I would rather use a normal for loop for this:

const products1 = [...Array(10).keys()].map((e) => "p"   e);
const companies1 = [...Array(10).keys()].map((e) => "c"   e);

console.log(getList(products1, companies1));

const products2 = [...Array(10).keys()].map((e) => "p"   e);
const companies2 = [...Array(1).keys()].map((e) => "c"   e);

console.log(getList(products2, companies2));

function getList(products, companies) {
  const list = [];
  const min = Math.min(products.length, companies.length);
  for (
    let i = 0, p = 0, c = 0;
    i < products.length   companies.length;
    i  = 1
  ) {
    // every fifth is a company, but only if there is a company left
    // or there are no more products
    if ((c < companies.length && i % 5 === 4) || p >= products.length) {
      list.push(companies[c  ]);
    } else {
      list.push(products[p  ]);
    }
  }
  return list;
}

Final component:

function HomePage() {
  let counter = 0;

  const dispatch = useDispatch();

  const productList = useSelector((state) => state.productList);
  const { error, loading, products } = productList;

  const companyList = useSelector((state) => state.companyList);
  const { companies } = companyList;

  function getList() {
    const list = [];
    const min = Math.min(products.length, companies.length);
    for (
      let i = 0, p = 0, c = 0;
      i < products.length   companies.length;
      i  = 1
    ) {
      if ((c < companies.length && i % 5 === 4) || p >= products.length) {
        list.push(<CompanyCard company={companies[c  ]} />);
      } else {
        list.push(<ProductCard product={products[p  ]} />);
      }
    }
    return list;
  }

  useEffect(() => {
    dispatch(listProducts(), listCompanies());
  }, [dispatch]);

  return (
    <>
      <Navbar />
      <div className="homePage">
        <div className="centerItemsContainer">
          <div className="productsContainer">{getList()}</div>
        </div>
      </div>
      <Footer />
    </>
  );
}

export default HomePage;

CodePudding user response:

{products.map((item, index) => (
  <>
    {(!!index && (index   1) % 5 === 0) ? (
      <>
        <ProductCard />
        <CompanyCard />
      </>
    ) : (
      <ProductCard />
    )}
  </>
)}
  • Related