**已关闭。**此问题为not reproducible or was caused by typos。目前不接受答复。
此问题是由打印错误或无法再重现的问题引起的。虽然类似的问题在这里可能是on-topic,但这个问题的解决方式不太可能帮助未来的读者。
昨天关门了。
Improve this question
当我打开主页jadi-domashno-alexohlin.vercel.app并点击导航栏中的链接“Ме ни”时,没有问题,但如果我直接导航到该页面,或者如果我只是刷新它jadi-domashno-alexohlin.vercel.app/meni,它会显示空白页面。我的代码在这里gitlab.com/alexohlin/jadi-domashno
这是我的app/meni/page.tsx代码
import { GotvacInterface } from "Types/types";
import MeniPage from "components/MeniPage";
import { Metadata } from "next";
export interface userPointInterface {
lat: number;
lng: number;
}
export const metadata: Metadata = {
title: "Мени - „Јади Домашно“",
description: "Погледнете го менито на платформата „Јади Домашно“",
openGraph: {
title: "Мени - „Јади Домашно“",
description: "Погледнете го менито на платформата „Јади Домашно“",
url: "https://jadi-domashno-alexohlin.vercel.app/meni",
},
twitter: {
title: "Мени - „Јади Домашно“",
description: "Погледнете го менито на платформата „Јади Домашно“",
},
appleWebApp: {
title: "Мени - „Јади Домашно“",
},
};
const fetchGotvaci = async () => {
const gotvaciRes = await fetch(
"https://band-frosted-brake.glitch.me/gotvaci?_embed=jadenja"
);
return gotvaciRes.json();
};
export default async function Meni() {
const gotvaci: GotvacInterface[] = await fetchGotvaci();
return <MeniPage gotvaci={gotvaci} />;
}
这是我在Meni页面中导入的MeniPage组件:
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
"use client";
import Image from "next/image";
import Link from "next/link";
import { useEffect, useState, useRef } from "react";
import { GotvacInterface } from "Types/types";
import { Rating } from "@mui/material";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import Types from "./Types";
import Jadenje from "./Jadenje";
import DatePicker from "./datepicker/DatePicker";
interface Props {
gotvaci: GotvacInterface[];
}
const MeniPage: React.FC<Props> = ({ gotvaci }) => {
const searchParams = useSearchParams();
const router = useRouter();
const pathname = usePathname();
const params = new URLSearchParams(searchParams);
const dateQuery = searchParams.get("date");
const dateInRouter = searchParams.get("date");
const typeiInRouter = searchParams.get("type");
const dostavaInRouter = searchParams.get("dostava");
const priceInRouter = searchParams.get("price");
const alergeniInRouter = searchParams.get("alergeni");
const ratingiInRouter = searchParams.get("rating");
const addressInRouter = searchParams.get("address");
const dostapnoPoPorachka = searchParams.get("dostapnoPoPorachka");
const resultsRef = useRef<HTMLDivElement>(null);
// useEffect(() => {
// if (searchParams.toString().length > 0) {
// window.scrollTo({
// top: resultsRef.current ? resultsRef.current.offsetTop - 120 : 0,
// behavior: "smooth",
// });
// }
// }, [searchParams]);
const [rawPickedDate, setRawPickedDate] = useState<string | null>(
dateQuery ? dateQuery.toString() : null
);
const changeQuery = (key: string, value: string) => {
params.set(key, value);
router.replace(`${pathname}?${params}`);
};
const deleteQuery = (key: string) => {
params.delete(key);
router.replace(`${pathname}?${params}`);
};
const handleTypeQueryClickEvent = (
e: React.MouseEvent<HTMLButtonElement, MouseEvent>,
type: string
) => {
if (e.currentTarget.dataset.checked === "false") {
e.currentTarget.dataset.checked = "true";
changeQuery("type", type);
} else {
e.currentTarget.dataset.checked = "false";
deleteQuery("type");
}
};
const jadenja = gotvaci.flatMap((gotvac) => gotvac.jadenja);
const filteredJadenja = addressInRouter
? jadenja.filter((jadenje) => {
return gotvaci
.filter((gotvac) => gotvac.address === addressInRouter)
.some((gotvac) => {
return gotvac.id === jadenje.gotvaciId;
});
})
: jadenja;
const filtered = filteredJadenja.filter(
(jadenje) =>
(dostavaInRouter
? jadenje.dostava ===
JSON.parse(dostavaInRouter ? dostavaInRouter.toString() : "")
: true) &&
(dateInRouter
? jadenje.dostapnoNa.includes(dateQuery ? dateQuery.toString() : "")
: true) &&
(priceInRouter ? jadenje.price <= Number(priceInRouter) : true) &&
(alergeniInRouter
? !jadenje.alergeni.some(
(alergen) => alergeniInRouter && alergeniInRouter.includes(alergen)
)
: true) &&
(typeiInRouter
? jadenje.type === typeiInRouter
? typeiInRouter.toString()
: ""
: true) &&
(ratingiInRouter
? Number(ratingiInRouter) <=
Math.ceil(
jadenje.feedback.reduce((accumulator, object) => {
return accumulator + object.stars;
}, 0) / jadenje.feedback.length
)
: true) &&
(dostapnoPoPorachka
? jadenje.dostapnoPoPorachka === Boolean(dostapnoPoPorachka)
? Boolean(dostapnoPoPorachka)
: ""
: true)
);
const maxPrice: number = Math.max(...jadenja.map((jadenje) => jadenje.price));
const minPrice: number = Math.min(...jadenja.map((jadenje) => jadenje.price));
// const [end, setEnd] = useState(9);
// const sliceJadenja = filtered.slice(0, end);
const uniqueTypes = gotvaci
.map((gotvac) => gotvac.jadenja.map((jadenje) => jadenje.type))
.flat()
.filter((value, index, self) => self.indexOf(value) === index);
return (
<div className="container py-5">
<section className="row align-items-center justify-content-center">
<div className="col-12 mb-5">
<div className="row align-items-center">
<div className="col-1 offset-3 d-none d-sm-flex">
<span className="w-100 bg-danger bg-opacity-50 mx-auto d-inline-block line" />
</div>
<div className="col-12 col-sm-4">
<h1 className="text-center mb-0 display-5">Мени</h1>
</div>
<div className="col-1 d-none d-sm-flex">
<span className="w-100 bg-danger bg-opacity-50 mx-auto d-inline-block line" />
</div>
</div>
</div>
<div className="col-12 col-lg-10">
<DatePicker
selectDate={rawPickedDate}
type="day"
startDate={new Date()}
getSelectedDay={(val: Date) => {
setRawPickedDate(val.toString());
}}
/>
{dateQuery && (
<div className="col-12 mt-3 text-center">
<button
onClick={() => deleteQuery("date")}
className={"btn btn-danger text-white"}
>
Види ги јадењата од сите датуми
</button>
</div>
)}
</div>
<div className="col-12 my-5">
<div className="row justify-content-lg-center align-items-center">
{uniqueTypes.map((type) => (
<Types
key={type}
handleTypeQueryClickEvent={handleTypeQueryClickEvent}
type={type}
searchParams={typeiInRouter ? typeiInRouter : ""}
/>
))}
</div>
</div>
<div className="col-12" ref={resultsRef}>
<div className="row">
<div className="col-12 col-md-3 mb-3 mb-md-0">
<div className="row py-3 px-2 shadow border-1 border rounded-1 bg-primary">
<div className="col-12 position-relative mb-4">
<select
value={addressInRouter ? addressInRouter : ""}
className="form-select px-5 rounded-3 border-0 shadow py-2"
onChange={(e) =>
e.target.value === ""
? deleteQuery("address")
: changeQuery("address", e.target.value)
}
>
{addressInRouter ? (
<>
<option value="" className="text-danger fw-bold">
Избриши филтер
</option>
<option value={addressInRouter}>
{addressInRouter}
</option>
</>
) : (
<option value="">Локација</option>
)}
{gotvaci.map((gotvac) => (
<option
key={`address-${gotvac.id}`}
value={gotvac.address}
>
{gotvac.address}
</option>
))}
</select>
<i className="bi bi-geo-alt-fill position-absolute h3 text-danger mb-0" />
</div>
<div className="col-12 pb-4 border-bottom">
<div className="form-check mb-2 ps-0">
<input
className="form-check-input float-end rounded-circle fs-5"
type="checkbox"
value={new Date().toLocaleDateString()}
id="dostapnoVednas"
checked={
dateQuery === new Date().toLocaleDateString()
? true
: false
}
onChange={(e) => {
if (dostapnoPoPorachka) {
deleteQuery("dostapnoPoPorachka");
}
if (e.target.checked) {
changeQuery("date", e.target.value);
setRawPickedDate(e.target.value);
} else {
deleteQuery("date");
}
}}
/>
<label
className="form-check-label float-start me-2 fs-5"
htmlFor="dostapnoVednas"
>
Достапно веднаш
</label>
</div>
<div className="form-check mb-2 ps-0">
<input
className="form-check-input float-end rounded-circle fs-5"
type="checkbox"
value={new Date(
+new Date().setHours(0, 0, 0, 0) + 86400000
).toLocaleDateString()}
id="dostapnoUtre"
checked={
dateQuery ===
new Date(
+new Date().setHours(0, 0, 0, 0) + 86400000
).toLocaleDateString()
? true
: false
}
onChange={(e) => {
if (dostapnoPoPorachka) {
deleteQuery("dostapnoPoPorachka");
}
if (e.target.checked) {
changeQuery("date", e.target.value);
// setRawPickedDate(e.target.value);
} else {
deleteQuery("date");
}
}}
/>
<label
className="form-check-label float-start me-2 fs-5"
htmlFor="dostapnoUtre"
>
Достапно утре
</label>
</div>
<div className="form-check ps-0">
<input
className="form-check-input float-end rounded-circle fs-5"
type="checkbox"
id="dostapnoPoPoracka"
checked={dostapnoPoPorachka ? true : false}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
if (dateQuery) {
deleteQuery("date");
}
if (!e.target.checked) {
deleteQuery("dostapnoPoPorachka");
} else {
changeQuery("dostapnoPoPorachka", "true");
}
}}
/>
<label
className="form-check-label float-start me-2 fs-5"
htmlFor="dostapnoPoPoracka"
>
Достапно по порачка
</label>
</div>
</div>
<div className="col-12 py-4 border-bottom">
<p className="label fs-5">Филтрирај по цена:</p>
{typeof priceInRouter === "string" &&
Number(priceInRouter) > 0 && (
<span className="bg-danger text-white p-2 rounded-circle">
{Number(priceInRouter) + " ден."}
</span>
)}
<input
style={{
appearance: "none",
backgroundColor: "#fe724d",
borderRadius: "50px",
}}
className="w-100 mt-2 fs-5 fs-5"
type="range"
role="progressbar"
aria-label="Example with label"
aria-valuenow={priceInRouter ? Number(priceInRouter) : 0}
aria-valuemin={minPrice}
aria-valuemax={maxPrice}
min={minPrice}
max={maxPrice}
value={priceInRouter ? Number(priceInRouter) : 0}
onChange={(e) => changeQuery("price", e.target.value)}
step={1}
/>
<div className="d-flex justify-content-between mt-2">
<p className="mb-0 fs-5">{minPrice} ден.</p>
<p className="mb-0 fs-5">{maxPrice} ден.</p>
</div>
</div>
<div className="col-12 py-4 border-bottom">
<p className="fs-5">Алергени:</p>
{jadenja
.map((item) => item.alergeni)
.flat(1)
.filter(
(value, index, self) => self.indexOf(value) === index
)
.map((alergen, index) => (
<span key={"key" + alergen + index}>
<input
type="checkbox"
className="btn-check"
id={alergen}
checked={
typeof alergeniInRouter === "string" &&
alergeniInRouter.includes(alergen)
}
value={alergen}
onClick={(e) => {
if (e.currentTarget.checked) {
changeQuery(
"alergeni",
alergeniInRouter
? alergeniInRouter +
"," +
e.currentTarget.value
: e.currentTarget.value
);
} else {
const neww =
alergeniInRouter &&
typeof alergeniInRouter === "string"
? alergeniInRouter
.split(",")
.filter(
(value) =>
value !== e.currentTarget.value
)
.join()
: "";
neww === ""
? deleteQuery("alergeni")
: changeQuery("alergeni", neww);
}
}}
/>
<label
className={`btn btn-danger text-white mb-2 me-2 shadow-sm ${
typeof alergeniInRouter === "string" &&
alergeniInRouter.includes(alergen)
? "text-decoration-line-through"
: null
}`}
htmlFor={alergen}
>
{alergen}
</label>
</span>
))}
</div>
<div className="col-12 py-4 border-bottom">
<p className="fs-5">Покажи по рејтинг:</p>
<div className="form-check mb-2 ps-0">
<input
className="form-check-input float-end fs-5"
type="radio"
value="3"
name="rating"
id="rating3"
checked={ratingiInRouter === "3"}
onClick={() => {
if (ratingiInRouter !== "3") {
changeQuery("rating", "3");
} else {
deleteQuery("rating");
}
}}
/>
<label
className="pe-5 form-check-label d-flex align-items-center fs-5"
htmlFor="rating3"
>
<Rating
readOnly
name="size-medium"
defaultValue={3}
max={3}
size="medium"
className="text-danger me-auto"
/>
3+
</label>
</div>
<div className="form-check mb-2 ps-0">
<input
className="form-check-input float-end fs-5"
type="radio"
name="rating"
id="rating4"
value="4"
checked={ratingiInRouter === "4"}
onClick={() => {
if (ratingiInRouter !== "4") {
changeQuery("rating", "4");
} else {
deleteQuery("rating");
}
}}
/>
<label
className="pe-5 form-check-label d-flex align-items-center fs-5"
htmlFor="rating4"
>
<Rating
readOnly
name="size-medium"
defaultValue={4}
max={4}
size="medium"
className="text-danger me-auto"
/>
4+
</label>
</div>
<div className="form-check ps-0">
<input
className="form-check-input float-end fs-5"
type="radio"
name="rating"
id="rating5"
value="5"
checked={ratingiInRouter === "5"}
onClick={() => {
if (ratingiInRouter !== "5") {
changeQuery("rating", "5");
} else {
deleteQuery("rating");
}
}}
/>
<label
className="pe-5 form-check-label d-flex align-items-center fs-5"
htmlFor="rating5"
>
<Rating
readOnly
name="size-medium"
defaultValue={5}
max={5}
size="medium"
className="text-danger me-auto"
/>
5
</label>
</div>
</div>
<div className="col-12 pt-4">
<div className="form-check mb-2 ps-0">
<input
className="form-check-input float-end fs-5"
type="radio"
name="dostava"
id="dostava"
value="dostava"
checked={dostavaInRouter === "true"}
onClick={() => {
if (dostavaInRouter !== "true") {
changeQuery("dostava", "true");
} else {
deleteQuery("dostava");
}
}}
/>
<label
className="form-check-label d-flex align-items-center pe-5 fs-5"
htmlFor="dostava"
>
<p className="mb-0 fs-5">Достава</p>
<i className="d-flex justify-content-center align-items-center height-30px width-30px ms-auto bi bi-truck text-danger rounded-circle shadow-sm" />
</label>
</div>
<div className="form-check ps-0">
<input
className="form-check-input float-end fs-5"
type="radio"
name="dostava"
id="podiganje"
value="podiganje"
checked={dostavaInRouter === "false"}
onClick={() => {
if (dostavaInRouter !== "false") {
changeQuery("dostava", "false");
} else {
deleteQuery("dostava");
}
}}
/>
<label
className="form-check-label d-flex align-items-center pe-5 fs-5"
htmlFor="podiganje"
>
<p className="mb-0 fs-5">Подигање</p>
<i className="d-flex justify-content-center align-items-center height-30px width-30px ms-auto bi bi-truck crossed text-danger rounded-circle shadow-sm" />
</label>
</div>
</div>
{Object.keys(searchParams).length > 0 && (
<div className="col-12 pt-4 text-center">
<Link
href="/meni"
className="btn btn-warning text-white bg-warning bg-opacity-75 border-0"
>
Ресетирај ги филтрите
</Link>
</div>
)}
</div>
</div>
<div className="col-12 col-md-9">
<div className="row p-3 ms-md-3 box-shadow border-1 border rounded-1 bg-primary bg-opacity-75 shadow">
{typeiInRouter && (
<h2 className="col-12 mb-4 text-dark text-opacity-75 text-center text-capitalize">
{typeiInRouter}
</h2>
)}
{jadenja.map((jadenje) => (
<Jadenje
key={jadenje.id}
gotvaci={gotvaci}
jadenje={jadenje}
/>
))}
{/* {
sliceJadenja.length > 0 ? (
sliceJadenja.map((jadenje) => (
<Jadenje
key={jadenje.id}
gotvaci={gotvaci}
jadenje={jadenje}
/>
))
) : (
<div className="col-12 text-center">
<div className="row align-items-center">
<h2 className="h3 col-8">
Нема резултати за пребарувањето
</h2>
<div className="col-4">
<Image
alt="Нема резултати за пребарувањето"
width="100"
height="100"
src="/icons/no-results.png"
/>
</div>
<div className="col-12 mt-4">
<Link
className="btn btn-warning text-white bg-warning bg-opacity-75 border-0"
href="/meni"
>
Ресетирај ги филтрите
</Link>
</div>
</div>
</div>
)} */}
{/* {end < filtered.length && (
<div className="col-12 col-sm-6 offset-sm-3 mt-1 text-center">
<button
onClick={() => setEnd(end + 9)}
className="btn btn-danger text-white"
>
Види повеќе
</button>
</div>
)} */}
</div>
</div>
</div>
</div>
</section>
</div>
);
};
export default MeniPage;
1条答案
按热度按时间2vuwiymt1#
我发现我的错误,我把服务器端组件到客户端组件..