The useProducts hook manages product inventory operations including search, category filtering, pagination, and modal state for product CRUD operations.
Import
import { useProducts } from '@hooks/useProducts';
Basic Usage
function ProductsPage() {
const {
searchTerm,
handleSearch,
categories,
selectedCategory,
handleCategoryChange,
currentProducts,
currentPage,
totalPages,
setCurrentPage,
openModal,
closeModal,
activeModal,
selectedProduct
} = useProducts();
return (
<div>
{/* Search and filter controls */}
<input
value={searchTerm}
onChange={handleSearch}
placeholder="Search products..."
/>
<select value={selectedCategory} onChange={handleCategoryChange}>
{categories.map(cat => (
<option key={cat} value={cat}>{cat}</option>
))}
</select>
{/* Product list */}
{currentProducts.map(product => (
<div key={product.id}>
<h3>{product.nombre}</h3>
<button onClick={() => openModal('details', product)}>
View Details
</button>
</div>
))}
{/* Pagination */}
<button
disabled={currentPage === 1}
onClick={() => setCurrentPage(currentPage - 1)}
>
Previous
</button>
<span>Page {currentPage} of {totalPages}</span>
<button
disabled={currentPage === totalPages}
onClick={() => setCurrentPage(currentPage + 1)}
>
Next
</button>
</div>
);
}
Return Value
Current search query string
handleSearch
(e: React.ChangeEvent<HTMLInputElement>) => void
Handler for search input changes. Automatically resets to page 1 when search term changes.
Array of unique product categories plus “TODAS” (all) option. Computed from product database.
Currently selected category filter. Default is “TODAS”.
handleCategoryChange
(e: React.ChangeEvent<HTMLSelectElement>) => void
Handler for category filter changes. Resets to page 1 when category changes.
Paginated array of products matching current search and category filters
Current page number (1-indexed)
Total number of pages based on filtered results and items per page
Function to change the current page
Number of items displayed per page. Default is 10.
handleItemsPerPageChange
(e: React.ChangeEvent<HTMLSelectElement>) => void
Handler to change items per page setting. Resets to page 1 when changed.
activeModal
'details' | 'add' | 'edit' | 'delete' | null
Currently open modal type, or null if no modal is open
openModal
(type: ModalType, product?: any) => void
Opens a modal of the specified type with optional product data
Closes the active modal and clears selected product
Currently selected product for modal operations
Total count of filtered products (before pagination)
Product Type
interface Product {
id: string;
nombre: string;
categoria: string;
codigoBarras: string;
precioVenta: number;
unidadMedida: string;
afectacionIgv: string;
frecuenciaCambioKm?: number;
}
Features
Multi-Filter Search
Search products by name, barcode, or category simultaneously:
const { searchTerm, handleSearch, currentProducts } = useProducts();
// Products are filtered in real-time across multiple fields
Category Management
Dynamic category list extracted from product database:
const { categories, selectedCategory, handleCategoryChange } = useProducts();
// Categories include "TODAS" plus all unique categories from products
// Categories: ["TODAS", "Aceites de Motor", "Filtros", "Refrigerantes", "Repuestos"]
Built-in pagination with customizable page size:
const {
currentProducts,
currentPage,
totalPages,
itemsPerPage,
handleItemsPerPageChange
} = useProducts();
// Users can select 10, 20, or 50 items per page
Modal State Management
Centralized modal state for product operations:
const { activeModal, openModal, closeModal, selectedProduct } = useProducts();
// Open modals for different operations
openModal('details', product); // View product details
openModal('add'); // Add new product
openModal('edit', product); // Edit existing product
openModal('delete', product); // Delete product
Data Source
Products are retrieved from the mock database (@data/db):
src/data/mock/products.ts
export const productsData = {
products: [
{
id: "prod-001",
nombre: "Aceite Mobil Super 5W-30",
categoria: "Aceites de Motor",
codigoBarras: "7501234567890",
precioVenta: 45.00,
unidadMedida: "GAL",
afectacionIgv: "10",
frecuenciaCambioKm: 5000
}
// ... more products
]
};
Best Practices
Reset pagination when filters change to avoid empty pages. The hook handles this automatically in handleSearch and handleCategoryChange.
The hook uses useMemo for filtered results and pagination to optimize performance and prevent unnecessary re-renders.
Modal state is local to the hook. If you need to share product selection across components, consider lifting state up or using Redux.