improve: improved performance of menu list
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
// components/menu/MenuItem.tsx
|
||||
'use client'
|
||||
|
||||
import { memo } from "react";
|
||||
import Image from "next/image";
|
||||
import PlusIcon from "@/components/icons/PlusIcon";
|
||||
import MinusIcon from "@/components/icons/MinusIcon";
|
||||
import { useReceiptStore } from "@/zustand/receiptStore";
|
||||
|
||||
interface MenuItemProps {
|
||||
food: {
|
||||
id: number
|
||||
name: string;
|
||||
contains: string;
|
||||
price: string;
|
||||
};
|
||||
}
|
||||
|
||||
const MenuItem = ({ food }: MenuItemProps) => {
|
||||
const quantity = useReceiptStore(state => state.items[food.id]?.quantity || 0);
|
||||
|
||||
const increment = useReceiptStore(state => state.increment);
|
||||
const decrement = useReceiptStore(state => state.decrement);
|
||||
|
||||
return (
|
||||
<div className="flex gap-4 w-full">
|
||||
<Image
|
||||
className="rounded-xl w-28 h-28"
|
||||
src={"/assets/images/food-preview.png"}
|
||||
height={100}
|
||||
width={100}
|
||||
alt="Food image"
|
||||
/>
|
||||
<div className="w-full h-full inline-flex flex-col justify-between">
|
||||
<div>
|
||||
<div className="text-sm2 font-semibold">{food.name}</div>
|
||||
<div className="text-[#7F7F7F] text-xs leading-5 font-normal mt-2">
|
||||
{food.contains}
|
||||
</div>
|
||||
</div>
|
||||
<div className="inline-flex justify-between w-full items-end">
|
||||
<span className="w-full" dir="ltr">{food.price} T</span>
|
||||
<div className="bg-background max-w-[115px] rounded-lg w-full h-8 inline-flex py-1 px-[5px] justify-between items-center gap-2">
|
||||
{quantity <= 0 ? (
|
||||
<button
|
||||
onClick={() => increment(food.id)}
|
||||
className="inline-flex w-full justify-center items-center gap-2"
|
||||
>
|
||||
<PlusIcon />
|
||||
<div className="text-sm2 pt-0.5 font-semibold">افزودن</div>
|
||||
</button>
|
||||
) : (
|
||||
<>
|
||||
<button
|
||||
onClick={() => increment(food.id)}
|
||||
className="bg-white rounded-sm p-2"
|
||||
>
|
||||
<PlusIcon />
|
||||
</button>
|
||||
<div className="text-sm2 pt-0.5 font-semibold">{quantity}</div>
|
||||
<button
|
||||
onClick={() => decrement(food.id)}
|
||||
className="bg-white rounded-sm p-2"
|
||||
>
|
||||
<MinusIcon />
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(MenuItem);
|
||||
@@ -1,15 +1,23 @@
|
||||
import React from 'react';
|
||||
|
||||
type Props = {
|
||||
children: React.ReactNode;
|
||||
children: React.ReactNode;
|
||||
} & React.HTMLAttributes<HTMLDivElement>;
|
||||
|
||||
function MenuItemRenderer({ children, ...rest }: Props) {
|
||||
return (
|
||||
<div {...rest} className={`${rest.className} transition-all duration-200 ease-out w-full h-36 bg-white rounded-3xl px-4 pt-3.5 pb-3 flex justify-between gap-4`}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
function MenuItemRendererComponent({ children, ...rest }: Props) {
|
||||
return (
|
||||
<div
|
||||
{...rest}
|
||||
className={`${rest.className} transition-all duration-200 ease-out w-full h-36 bg-white rounded-3xl px-4 pt-3.5 pb-3 flex justify-between gap-4`}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Memoize with shallow comparison of props
|
||||
const MenuItemRenderer = React.memo(MenuItemRendererComponent, (prevProps, nextProps) => {
|
||||
return prevProps.className === nextProps.className && prevProps.children === nextProps.children;
|
||||
});
|
||||
|
||||
export default MenuItemRenderer;
|
||||
|
||||
Reference in New Issue
Block a user