perf(supplies): optimize React components with memo and callbacks
ФАЗА 2: Оптимизация производительности завершена: - Обернуты все блок-компоненты в React.memo для предотвращения лишних ререндеров - Добавлены useCallback для всех обработчиков событий в главном компоненте - Оптимизированы зависимости для минимизации пересоздания функций - Страница остается полностью функциональной Компоненты с memo: SuppliersBlock, ProductCardsBlock, DetailedCatalogBlock, CartBlock Callbacks: handleSupplierSelect, handleProductAdd, handleQuantityChange, handleRecipeChange 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
6
dev.log
6
dev.log
@ -41,3 +41,9 @@
|
||||
POST /api/graphql 200 in 936ms
|
||||
POST /api/graphql 200 in 638ms
|
||||
POST /api/graphql 200 in 489ms
|
||||
POST /api/graphql 200 in 560ms
|
||||
POST /api/graphql 200 in 473ms
|
||||
POST /api/graphql 200 in 1273ms
|
||||
POST /api/graphql 200 in 1323ms
|
||||
POST /api/graphql 200 in 475ms
|
||||
POST /api/graphql 200 in 907ms
|
||||
|
@ -8,13 +8,14 @@
|
||||
'use client'
|
||||
|
||||
import { ShoppingCart, X } from 'lucide-react'
|
||||
import React from 'react'
|
||||
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { DatePicker } from '@/components/ui/date-picker'
|
||||
|
||||
import type { CartBlockProps } from '../types/supply-creation.types'
|
||||
|
||||
export function CartBlock({
|
||||
export const CartBlock = React.memo(function CartBlock({
|
||||
selectedGoods,
|
||||
selectedSupplier,
|
||||
deliveryDate,
|
||||
@ -155,4 +156,4 @@ export function CartBlock({
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
import { Package, Settings, Building2 } from 'lucide-react'
|
||||
import Image from 'next/image'
|
||||
import React from 'react'
|
||||
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
import { DatePicker } from '@/components/ui/date-picker'
|
||||
@ -24,7 +25,7 @@ import type {
|
||||
SellerConsumable,
|
||||
} from '../types/supply-creation.types'
|
||||
|
||||
export function DetailedCatalogBlock({
|
||||
export const DetailedCatalogBlock = React.memo(function DetailedCatalogBlock({
|
||||
allSelectedProducts,
|
||||
productRecipes,
|
||||
fulfillmentServices,
|
||||
@ -129,7 +130,7 @@ export function DetailedCatalogBlock({
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
// Компонент детальной карточки товара с рецептурой
|
||||
interface ProductDetailCardProps {
|
||||
|
@ -9,12 +9,17 @@
|
||||
|
||||
import { Package, Plus } from 'lucide-react'
|
||||
import Image from 'next/image'
|
||||
import React from 'react'
|
||||
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
|
||||
import type { ProductCardsBlockProps } from '../types/supply-creation.types'
|
||||
|
||||
export function ProductCardsBlock({ products, selectedSupplier, onProductAdd }: ProductCardsBlockProps) {
|
||||
export const ProductCardsBlock = React.memo(function ProductCardsBlock({
|
||||
products,
|
||||
selectedSupplier,
|
||||
onProductAdd,
|
||||
}: ProductCardsBlockProps) {
|
||||
if (!selectedSupplier) {
|
||||
return (
|
||||
<div className="bg-white/10 backdrop-blur-xl border border-white/20 rounded-2xl p-6">
|
||||
@ -141,4 +146,4 @@ export function ProductCardsBlock({ products, selectedSupplier, onProductAdd }:
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
@ -8,13 +8,14 @@
|
||||
'use client'
|
||||
|
||||
import { Search } from 'lucide-react'
|
||||
import React from 'react'
|
||||
|
||||
import { OrganizationAvatar } from '@/components/market/organization-avatar'
|
||||
import { Input } from '@/components/ui/input'
|
||||
|
||||
import type { SuppliersBlockProps } from '../types/supply-creation.types'
|
||||
|
||||
export function SuppliersBlock({
|
||||
export const SuppliersBlock = React.memo(function SuppliersBlock({
|
||||
suppliers,
|
||||
selectedSupplier,
|
||||
searchQuery,
|
||||
@ -132,7 +133,7 @@ export function SuppliersBlock({
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
// Утилитарная функция для меток рынков (временно, потом перенести в хук)
|
||||
function getMarketLabel(market?: string) {
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
import { ArrowLeft } from 'lucide-react'
|
||||
import { useRouter } from 'next/navigation'
|
||||
import React, { useCallback } from 'react'
|
||||
|
||||
import { Sidebar } from '@/components/dashboard/sidebar'
|
||||
import { Button } from '@/components/ui/button'
|
||||
@ -89,23 +90,30 @@ export function CreateSuppliersSupplyPage() {
|
||||
} = useRecipeBuilder({ selectedFulfillment })
|
||||
|
||||
// Обработчики событий для блоков
|
||||
const handleSupplierSelect = (supplier: GoodsSupplier) => {
|
||||
const handleSupplierSelect = useCallback(
|
||||
(supplier: GoodsSupplier) => {
|
||||
setSelectedSupplier(supplier)
|
||||
// Сбрасываем выбранные товары при смене поставщика
|
||||
setAllSelectedProducts([])
|
||||
setSelectedGoods([])
|
||||
}
|
||||
},
|
||||
[setSelectedSupplier, setAllSelectedProducts, setSelectedGoods],
|
||||
)
|
||||
|
||||
const handleProductAdd = (product: GoodsProduct) => {
|
||||
const handleProductAdd = useCallback(
|
||||
(product: GoodsProduct) => {
|
||||
const quantity = getProductQuantity(product.id) || 1
|
||||
addProductToSelected(product, quantity)
|
||||
initializeProductRecipe(product.id)
|
||||
|
||||
// Добавляем в корзину
|
||||
addToCart(product, quantity)
|
||||
}
|
||||
},
|
||||
[getProductQuantity, addProductToSelected, initializeProductRecipe, addToCart],
|
||||
)
|
||||
|
||||
const handleQuantityChange = (productId: string, quantity: number) => {
|
||||
const handleQuantityChange = useCallback(
|
||||
(productId: string, quantity: number) => {
|
||||
updateSelectedProductQuantity(productId, quantity)
|
||||
|
||||
// Синхронизируем с корзиной
|
||||
@ -116,14 +124,19 @@ export function CreateSuppliersSupplyPage() {
|
||||
removeFromCart(productId)
|
||||
removeProductFromSelected(productId)
|
||||
}
|
||||
}
|
||||
},
|
||||
[updateSelectedProductQuantity, allSelectedProducts, addToCart, removeFromCart, removeProductFromSelected],
|
||||
)
|
||||
|
||||
const handleRecipeChange = (productId: string, recipe: ProductRecipe) => {
|
||||
const handleRecipeChange = useCallback(
|
||||
(productId: string, recipe: ProductRecipe) => {
|
||||
setProductRecipes((prev) => ({
|
||||
...prev,
|
||||
[productId]: recipe,
|
||||
}))
|
||||
}
|
||||
},
|
||||
[setProductRecipes],
|
||||
)
|
||||
|
||||
// Обработчик ошибок
|
||||
if (suppliersError) {
|
||||
|
Reference in New Issue
Block a user