我需要Map下面的对象,如{ ...product.images[0] }
,{ ...product.type[0] }
,{ ...product.productPackages[0] }
,在我下面的代码。
这是我的目标:
export const customImage = [
{
status: false,
image: null,
price: 10,
},
];
字符串
我进口了这个
import { customImage } from "@/utils/customImage";
型
但当前声明是错误的。[this one selectedCustomImage: customImage,
](我得到了下面的错误这个Map)
类型“{状态:boolean;图片:无效;价格:数量;}[]“缺少类型”SelectedCustomImageType“中的以下属性:status、image、pricets(2739)
(属性)selectedCustomImage:SelectedCustomImageType
请帮助我正确Map这个数组。
这是我的代码:
"use client";
import { useCart } from "@/hooks/useCart";
import { customImage } from "@/utils/customImage";
import { formatPrice } from "@/utils/formatprice";
import { Rating } from "@mui/material";
import { useRouter } from "next/navigation";
import { useCallback, useEffect, useState } from "react";
import { MdCheckCircle } from "react-icons/md";
import toast from "react-hot-toast";
import Button from "@/app/components/Button";
import CustomImageInput from "@/app/components/inputs/CustomImageInput";
import PackageButton from "@/app/components/inputs/PackageButton";
import ProductImage from "@/app/components/products/ProductImage";
import SetQuantity from "@/app/components/products/SetQuantity";
import TypeImage from "@/app/components/products/TypeImage";
import SetColor from "@/app/components/products/setColor";
import SetType from "@/app/components/products/setType";
interface ProductDetailsProps {
product: any;
}
export type CartProductType = {
id: string;
name: string;
description: string;
category: string;
brand: string;
selectedImg: SelectedImgType;
selectedProduct: SelectedProductType;
quantity: number;
selectedPackage: SelectedPackageType;
price: number;
productPrice: number;
file: any;
selectedCustomImage: SelectedCustomImageType;
};
// customImagePrice: number;
export type SelectedImgType = {
color: string;
colorCode: string;
image: string;
};
export type SelectedProductType = {
type: string;
typeCode: string;
typePrice: number;
image: string;
};
export type SelectedPackageType = {
packaging: string;
price: number;
image: string;
};
export type SelectedCustomImageType = {
status: boolean;
image: string;
price: number;
};
export type CustomImage = {
status: boolean;
image: File | null;
price: number;
};
const Horizontal = () => {
return <hr className="w-[30% my-2]" />;
};
const ProductDetails: React.FC<ProductDetailsProps> = ({ product }) => {
const router = useRouter();
const { handleAddProductToCart, cartProducts } = useCart();
const [isProductInCart, setIsProductInCart] = useState(false);
const [cartProduct, setCartProduct] = useState<CartProductType>({
id: product.id,
name: product.name,
description: product.description,
category: product.category,
brand: product.brand,
selectedImg: { ...product.images[0] },
selectedProduct: { ...product.type[0] },
quantity: 1,
price: product.price,
productPrice: product.price,
selectedPackage: { ...product.productPackages[0] },
file: null,
selectedCustomImage: customImage,
});
useEffect(() => {
setIsProductInCart(false);
if (cartProducts) {
const existingIndex = cartProducts.findIndex(
(item) => item.id === product.id,
);
if (existingIndex > -1) {
setIsProductInCart(true);
}
}
}, [cartProducts]);
const productrating =
product.reviews.reduce((acc: number, item: any) => item.rating + acc, 0) /
product.reviews.length;
const handleColorSelect = useCallback(
(value: SelectedImgType) => {
setCartProduct((prev) => {
return { ...prev, selectedImg: value };
});
},
[cartProduct.selectedImg],
);
const handleCustomImageSelect = useCallback(
(value: SelectedProductType) => {
setCartProduct((prev) => {
if ((cartProduct.file = null)) {
}
return {
...prev,
selectedProduct: value,
price: product.price,
productPrice: value.typePrice * cartProduct.quantity,
customImagePrice: value.typePrice * cartProduct.quantity,
};
});
},
[cartProduct.selectedProduct],
);
const handleTypeSelect = useCallback(
(value: SelectedProductType) => {
setCartProduct((prev) => {
return {
...prev,
selectedProduct: value,
price: product.price,
productPrice: value.typePrice * cartProduct.quantity,
customImagePrice: value.typePrice * cartProduct.quantity,
};
});
},
[cartProduct.selectedProduct],
);
const handlePackageSelect = useCallback(
(value: SelectedPackage) => {
setCartProduct((prev) => {
return {
...prev,
selectedPackage: value,
price: product.price,
productPrice: value.price * cartProduct.quantity,
customImagePrice: value.price * cartProduct.quantity,
};
});
},
[cartProduct.selectedProduct],
);
const handleQtyIncrease = useCallback(() => {
if (cartProduct.quantity === 99) {
return;
}
setCartProduct((prev) => {
return { ...prev, quantity: ++prev.quantity };
});
}, [cartProduct]);
const handleQtyDecrease = useCallback(() => {
if (cartProduct.quantity === 1) {
return;
}
setCartProduct((prev) => {
return { ...prev, quantity: --prev.quantity };
});
}, [cartProduct]);
//console.log("this is cart product >>>>", cartProduct);
const [images, setImages] = useState<CustomImage[] | null>();
const addImageToState = useCallback((value: CustomImage) => {
setImages((prev) => {
if (!prev) {
return [value];
}
return [...prev, value];
});
}, []);
const removeImageFromState = useCallback((value: CustomImage) => {
setImages((prev) => {
if (prev) {
const filteredImages = prev.filter((item) => item.price != value.price);
return filteredImages;
}
return prev;
});
}, []);
const [isProductCreated, setIsProductCreated] = useState(false);
return (
<div>
<div>
{" "}
<div className="grid grid-cols-1 md:grid-cols-2 gap-12">
<ProductImage
cartProduct={cartProduct}
product={product}
handleColorSelect={handleColorSelect}
/>
<div className="flex flex-col gap-1 text-slate-700 text-sm">
<h2 className="text-3xl font-medium text-slate-700">
{product.name}
</h2>
<div className="flex items-center gap-2">
<Rating value={productrating} readOnly />
<div>{product.reviews.length} reviews</div>
</div>
<Horizontal />
<div className="text-justify">{product.description}</div>
<Horizontal />
<div>
<span className="font-semibold">CATEGORY : </span>
{product.category}
</div>
<div>
<span className="font-semibold">BRAND : </span>
{product.brand}
</div>
<div
className={
product.availablequantity > 0
? "text-teal-400"
: "text-rose-400"
}
>
{product.availablequantity > 0 ? "In Stock" : "Out of Stock"}
</div>
<Horizontal />
{isProductInCart ? (
<>
<p className="mb-2 text-slate-500 flex items-center gap-1">
<MdCheckCircle className="text-teal-400" size={20} />
<span>Product added to Cart</span>
</p>
<div className="max-w-[300px]">
<Button
label="View Cart"
outline
onClick={() => {
router.push("/cart");
}}
/>
</div>
</>
) : (
<>
<div>
<span className="font-semibold">TYPE : </span>
<TypeImage
cartProduct={cartProduct}
product={product}
handleTypeSelect={handleTypeSelect}
/>
<SetType
cartProduct={cartProduct}
type={product.type}
handleTypeSelect={handleTypeSelect}
/>
</div>
<Horizontal />
<SetColor
cartProduct={cartProduct}
images={product.images}
handleColorSelect={handleColorSelect}
/>
<Horizontal />
<SetQuantity
cartProduct={cartProduct}
handleQtyIncrease={handleQtyIncrease}
handleQtyDecrease={handleQtyDecrease}
/>
<Horizontal />
<div>
<div className="justify-self-end font-semibold">
<span className="font-semibold">PRICE : </span>
{formatPrice(product.price)}
</div>
</div>
<Horizontal />
<div>
<div className="justify-self-end font-semibold">
<span className="font-semibold">Packaging : </span>
{/** Add packaging type here grid grid-cols-2 gap-4 max-w-[300px] mt-6 mb-6*/}
</div>
<div className="">
<PackageButton
handlePackageSelect={handlePackageSelect}
cartProduct={cartProduct}
product={product}
label={product.productPackages}
price={[]}
/>
</div>
</div>
<Horizontal />
<div>
<div className="justify-self-end">
<span className="font-semibold">Custom Image : </span>
<div className="w-full flex flex-col flex-wrap gap-4">
<div>
<div className="font-bold subpixel-antialiased">
Add your company logo, name or any other custom image
which should be printed on your product.
</div>
<div className="text-sm italic mt-1">
Additional charges apply!
</div>
</div>
<div className="grid grid-cols-2 gap-3">
{customImage.map((item, index) => {
return (
<CustomImageInput
key={index}
item={item}
addImageToState={addImageToState}
removeImageFromState={removeImageFromState}
isProductCreated={isProductCreated}
cartProduct={cartProduct}
setCartProduct={setCartProduct}
handleCustomImageSelect={handleCustomImageSelect}
/>
);
})}
</div>
</div>
</div>
<div>{/* add image upload here */}</div>
</div>
<div>
<div className="justify-self-end font-semibold">
<span className="font-semibold">Total: </span>
{/* {cartProduct.isCustomImage
? formatPrice(
cartProduct.productPrice * cartProduct.quantity +
cartProduct.selectedPackage.price *
cartProduct.quantity
)
: formatPrice(
cartProduct.productPrice * cartProduct.quantity +
cartProduct.selectedPackage.price *
cartProduct.quantity +
cartProduct.customImagePrice
)} */}
{/* {formatPrice(
cartProduct.productPrice * cartProduct.quantity + cartProduct.selectedPackage.price *cartProduct.quantity)} */}
{formatPrice(
(cartProduct.productPrice =
(cartProduct.price +
cartProduct.selectedProduct.typePrice +
cartProduct.selectedPackage.price) *
cartProduct.quantity),
)}
<span className="font-semibold">
Type: {cartProduct.selectedProduct.typePrice}
</span>
<span className="font-semibold">
Package: {cartProduct.selectedPackage.price}
</span>
</div>
</div>
<div className="max-w-[300px] ">
<Button
label="Add To Cart"
onClick={() => handleAddProductToCart(cartProduct)}
/>
</div>
</>
)}
</div>
</div>
</div>
</div>
);
};
export default ProductDetails;
型
1条答案
按热度按时间ctehm74n1#
看起来使用的对象应该是一个数组,你只是忘记了在这里索引它:
字符串
你还必须赋值一个空字符串而不是null。
型
如果对象不需要是数组,请删除方括号:
型
然后完全删除map调用
型