Joe Starnes
Joe Starnes

Reputation: 491

PrimeReact carousel using function when using onPageChange?

I'm newer to react and I'm stumped by this issue. I'm using a primereact carousel and trying to do 2 things.

  1. In the item template I want to show 'Showing X of X orders'.... essentially showing where they are at in the array of orders.
  2. I want to reload the data each time the page is changed.

What I am running into is whenever I use this code below the carousel loses it's functionality. The left arrow is never enabled and the markers below the carousel is always set at one. So it's like it can no longer keep track of where it's at.

<div className="carousel-wrapper">
            <Carousel
              onPageChange={test}
              value={filteredOrders}
              numVisible={1}
              numScroll={1}
              responsiveOptions={[
                {
                  breakpoint: "1024px",
                  numVisible: 1,
                  numScroll: 1,
                },
                {
                  breakpoint: "768px",
                  numVisible: 1,
                  numScroll: 1,
                },
                {
                  breakpoint: "560px",
                  numVisible: 1,
                  numScroll: 1,
                },
              ]}
              itemTemplate={itemTemplate}
            />
          </div>

function test() {
    console.log("test");
  }

Even with this simple code here I can see in the console "test" every time I click the right arrow. But again the carousel loses functionality. If I remove the onPageChange line form the carousel it goes back to working.

Upvotes: 1

Views: 560

Answers (1)

Melloware
Melloware

Reputation: 12029

It is because when you added onPageChange you are telling the component you want to control paging. This is referred to as "uncontrolled mode" vs "controlled mode" where the component is handling the paging.

See this fully working example: https://stackblitz.com/edit/otq6af?file=src%2FApp.tsx

import React, { useState, useEffect } from 'react';
import { Button } from 'primereact/button';
import { Carousel } from 'primereact/carousel';
import { Tag } from 'primereact/tag';
import { ProductService } from './service/ProductService';

interface Product {
  id: string;
  code: string;
  name: string;
  description: string;
  image: string;
  price: number;
  category: string;
  quantity: number;
  inventoryStatus: string;
  rating: number;
}

export default function VerticalDemo() {
  const [products, setProducts] = useState<Product[]>([]);
  const [page, setPage] = useState<number>(0);

  const getSeverity = (product: Product) => {
    switch (product.inventoryStatus) {
      case 'INSTOCK':
        return 'success';

      case 'LOWSTOCK':
        return 'warning';

      case 'OUTOFSTOCK':
        return 'danger';

      default:
        return null;
    }
  };

  useEffect(() => {
    ProductService.getProductsSmall().then((data) =>
      setProducts(data.slice(0, 9))
    );
  }, []);

  const productTemplate = (product: Product) => {
    return (
      <div className="border-1 surface-border border-round m-2 text-center py-5 px-3">
        <div className="mb-3">
          <img
            src={`https://primefaces.org/cdn/primereact/images/product/${product.image}`}
            alt={product.name}
            className="w-6 shadow-2"
          />
        </div>
        <div>
          <h4 className="mb-1">{product.name}</h4>
          <h6 className="mt-0 mb-3">${product.price}</h6>
          <Tag
            value={product.inventoryStatus}
            severity={getSeverity(product)}
          ></Tag>
          <div className="mt-5 flex flex-wrap gap-2 justify-content-center">
            <Button icon="pi pi-search" className="p-button p-button-rounded" />
            <Button
              icon="pi pi-star-fill"
              className="p-button-success p-button-rounded"
            />
          </div>
        </div>
      </div>
    );
  };

  return (
    <div className="card flex justify-content-center">
      <Carousel
        value={products}
        numVisible={1}
        numScroll={1}
        orientation="vertical"
        verticalViewPortHeight="360px"
        itemTemplate={productTemplate}
        page={page}
        onPageChange={(e) => setPage(e.page)}
      />
    </div>
  );
}

Upvotes: 0

Related Questions