SaleSlider.tsx
import React, { useState } from "react";
import { SaleSliderItem } from "@/components/SaleSliderItem/SaleSliderItem";
import styles from "./SaleSlider.module.scss";
export function SaleSlider({ response }: { response: any }) {
const [currentIndex, setCurrentIndex] = useState(0);
const handleForward = () => {
if (currentIndex < response.sliderSaleList.length - 1) {
setCurrentIndex(currentIndex + 1);
} else {
setCurrentIndex(0);
}
};
const handleBackward = () => {
if (currentIndex > 0) {
setCurrentIndex(currentIndex - 1);
} else {
setCurrentIndex(response.sliderSaleList.length - 1);
}
};
if (
Array.isArray(response.sliderSaleList) &&
response.sliderSaleList.length > 0
) {
return (
<>
<div className={styles.sliderContainer}>
<button className={styles.sliderBtn} onClick={handleBackward}>
backward
</button>
<div className={styles.flexContainerPrimary}>
{response.sliderSaleList.map((item: any, idx: any) => (
<SaleSliderItem
item={item}
isVisible={idx === currentIndex}
key={idx}
currentIndex={currentIndex}
/>
))}
</div>
<button className={styles.sliderBtn} onClick={handleForward}>
forward
</button>
</div>
</>
);
} else {
return <div>Keine Produkte verfügbar</div>;
}
}
SaleSliderItem.tsx
import React from "react";
import styles from "./SaleSliderItem.module.scss";
export function SaleSliderItem({
item,
isVisible,
currentIndex,
}: {
item: any;
isVisible: boolean;
currentIndex: number;
}) {
return (
<div
className={styles.flexContainerSecondary}
style={{ display: isVisible ? "flex" : "none" }}>
{item.stageProductImage &&
item.stageProductImage.data &&
item.stageProductImage.data.attributes && (
<img
src={`${process.env.STRAPI_URL as string}${
item.stageProductImage.data.attributes.formats.small.url
}`}
alt={item.stageProductImage.data.attributes.alternativeText}
/>
)}
<div className={styles.flexContainerTertiary}>
{item.stageBestseller ? (
<p className={styles.bestseller}>Bestseller</p>
) : null}
<h1>{item.stageProductName}</h1>
<h3>€ {item.stageDiscountPrice}</h3>
<p>
{item.stageDiscountStartDate} ~ {item.stageDiscountEndDate}
</p>
<div>
<button>ADD TO CART</button>
<button>❤️</button>
</div>
<button>FIND SIMILAR STYLES</button>
</div>
</div>
);
}
JSON For convenience, the “id” of each “sliderSaleList” is repeated in the same format from 1 to 7.
{
"data": {
"id": 1,
"attributes": {
"createdAt": "2023-06-05T09:13:51.046Z",
"updatedAt": "2023-09-25T08:46:55.018Z",
"publishedAt": "2023-09-21T11:10:34.193Z",
"slug": "homepage",
"stageBrand": "SALE",
"sliderSaleList": [
{
"id": 1,
"stageDiscountStartDate": "2023-09-20T22:00:00.000Z",
"stageDiscountEndDate": "2023-09-27T22:00:00.000Z",
"stageBestseller": true,
"stageDiscountPrice": 28.99,
"stageProductName": "BROWN SNEAKERS",
"stageProductImage": {
"data": {
"id": 3,
"attributes": {
"name": "brown_sneakers.png",
"alternativeText": "brown_sneakers",
"caption": null,
"width": 693,
"height": 672,
"formats": {
"small": {
"ext": ".png",
"url": "/uploads/small_brown_sneakers_f99b1f226c.png",
"hash": "small_brown_sneakers_f99b1f226c",
"mime": "image/png",
"name": "small_brown_sneakers.png",
"path": null,
"size": 135.01,
"width": 500,
"height": 485
},
},
"hash": "brown_sneakers_f99b1f226c",
"ext": ".png",
"mime": "image/png",
"size": 58.09,
"url": "/uploads/brown_sneakers_f99b1f226c.png",
"previewUrl": null,
"provider": "local",
"provider_metadata": null,
"createdAt": "2023-09-21T15:55:42.086Z",
"updatedAt": "2023-09-21T15:55:42.086Z"
}
}
}
},
{
"id": 7,
"stageDiscountStartDate": "2023-08-31T22:00:00.000Z",
"stageDiscountEndDate": "2023-09-25T22:00:00.000Z",
"stageBestseller": true,
"stageDiscountPrice": 58.99,
"stageProductName": "CARGO TROUSERS",
"stageProductImage": {
"data": {
"id": 9,
"attributes": {
"name": "cargo_trousers.png",
"alternativeText": "cargo_trousers",
"caption": null,
"width": 598,
"height": 826,
"formats": {
"small": {
"ext": ".png",
"url": "/uploads/small_cargo_trousers_9d9cc4cc95.png",
"hash": "small_cargo_trousers_9d9cc4cc95",
"mime": "image/png",
"name": "small_cargo_trousers.png",
"path": null,
"size": 125.86,
"width": 362,
"height": 500
},
},
"hash": "cargo_trousers_9d9cc4cc95",
"ext": ".png",
"mime": "image/png",
"size": 68.64,
"url": "/uploads/cargo_trousers_9d9cc4cc95.png",
"previewUrl": null,
"provider": "local",
"provider_metadata": null,
"createdAt": "2023-09-24T20:38:35.849Z",
"updatedAt": "2023-09-24T22:34:04.160Z"
}
}
}
}
]
}
},
"meta": {
}
}
**I’m trying to create a slider with strapi. I want to write the slider logic separately from the slider item component. The forward and back buttons don’t work, obviously the console shows that the picture is mapped, but the next button doesn’t work.
FYI: (I also have this Warning in my Browser)
Warning: An error occurred during hydration. The server HTML was replaced with client content in <#document>.
Uncaught Error: Hydration failed because the initial UI does not match what was rendered on the server.
Can anyone help me with this?
I would really appreciate it:)!
I fetched my strapi address to page.tsx and I’m attaching JSON String here.**
