如何在 window 重新加载 nextJS 后保留状态变量的值?
How to persist the value of state variables after window reloads in nextJS?
简介
我正在用 nextJS 设计一个电子商务平台。它由这样的 T 恤页面组成。
单击四件 T 恤中的任何一件后,我转到了 slug.js
文件中的特定 T 恤页面,页面如下所示。
这就是我面临的问题。
问题
可以看到黑色T恤页面的URL是
http://localhost:3000/products/wear-the-chess-formula-S-Black
这是正确的,但在那之后如果我 select 任何颜色和尺寸变体,比如 (Green,M)
,它不会在重新加载后反映在 URL 中。您还可以在下图中看到左上角。重新加载后我又看到了黑色 T 恤图像。
为了这个功能,我构建了以下函数。
const refreshVariant = (newsize, newcolor) => {
let url = `http://localhost:3000/products/${colorSizeSlug[newcolor][newsize]["slug"]}`;
//console.log("url = ",url, "newcolor - ",newcolor, "newsize - ", newsize)
//console.log("newvaraint -", colorSizeSlug)
window.location = url;
};
我怎么想的?
我认为点击颜色按钮和尺寸下拉选项,颜色和尺寸的值发生变化,但在重新加载后,它又回到了初始值。
现场行为
我想要什么?
我想保留这两个状态变量的值 color & size,这样每次我们 select 颜色时,相同颜色的点就会突出显示并且同样反映在 URL 中。例如,如果我 select 绿色和 M 尺寸,那么绿色点应该用边框突出显示,这个 URL 应该出现
http://localhost:3000/products/wear-the-chess-formula-M-Green
代码
负责这个的文件是slug.js
import React, { useState } from "react";
import { useRouter } from "next/router";
import mongoose from "mongoose";
import Product from "../../models/Product";
//colosizeSlug :
// {
// Black: {S: {slug: "wear-the-chess-formula-1"}},
// Blue: {M: {slug: "wear-the-chess-formula-2"}},
// Green: {L: {slug: "wear-the-chess-formula-3"}},
// Red: {XL: {slug: "wear-the-chess-think-1"} ,XXL: {slug: "wear-the-chess-think-2"}}
// }
// MY LOGS
//date - 17-4-22
//issue of setColor & setSize is resolved but now the window reload functon disabled. It is beacuse when the page reloads , the state value of color and size revert back to the its initial value & not the current value. That's why you can see the updated url is not displayed in chrome tab.
const Slug = ({ addToCart, all_Tshirts, colorSizeSlug }) => {
//console.log(all_Tshirts, colorSizeSlug);
//console.log("keys = ",Object.keys(colorSizeSlug["Red"]))
const router = useRouter();
const { slug } = router.query;
const [pin, setPin] = useState();
const [isAvailable, setIsAvailable] = useState();
const [color, setColor] = useState(all_Tshirts[0].color);
const [size, setSize] = useState(all_Tshirts[0].size);
console.log("size =", size, " color = ", color);
const checkservicibilty = async () => {
let pins = await fetch("http://localhost:3000/api/pincode");
let pinjson = await pins.json();
//console.log(pin, pinjson);
if (pinjson.includes(pin)) {
setIsAvailable(true);
//console.log("Available");
} else {
setIsAvailable(false);
//console.log("NOt");
}
};
const onChangePin = (e) => {
setPin(e.target.value);
};
const refreshVariant = (newsize, newcolor) => {
let url = `http://localhost:3000/products/${colorSizeSlug[newcolor][newsize]["slug"]}`;
//console.log("url = ",url, "newcolor - ",newcolor, "newsize - ", newsize)
//console.log("newvaraint -", colorSizeSlug)
window.location = url;
};
return (
<>
<section className="text-gray-600 body-font overflow-hidden">
<div className="container px-5 py-16 mx-auto">
<div className="lg:w-4/5 mx-auto flex flex-wrap">
<img
alt="ecommerce"
className="lg:w-1/2 w-full h-80 lg:h-[36rem] object-cover object-top rounded"
src={`${colorSizeSlug[color][size]["url"]}`}
/>
<div className="lg:w-1/2 w-full lg:pl-10 lg:py-6 mt-6 lg:mt-0">
<h2 className="text-sm title-font text-gray-500 tracking-widest">
CHESS WEAR
</h2>
<h1 className="text-gray-900 text-3xl title-font font-medium mb-1">
Men's Chess Formula T-Shirt ( L-Black )
</h1>
<div className="flex mb-4">
<span className="flex items-center">
.
.
.
<span className="text-gray-600 ml-3">4 Reviews</span>
</span>
<span className="flex ml-3 pl-3 py-2 border-l-2 border-gray-200 space-x-2s">
.
.
.
</span>
</div>
<p className="leading-relaxed">
Fam locavore kickstarter distillery. Mixtape chillwave tumeric
sriracha taximy chia microdosing tilde DIY. XOXO fam indxgo
juiceramps cornhole raw denim forage brooklyn. Everyday carry +1
seitan poutine tumeric. Gastropub blue bottle austin listicle
pour-over, neutra jean shorts keytar banjo tattooed umami
cardigan.
</p>
<div className="flex mt-6 items-center pb-5 border-b-2 border-gray-100 mb-5">
<div className="flex">
<span className="mr-3">Color</span>
{Object.keys(colorSizeSlug).includes("Red") &&
Object.keys(colorSizeSlug["Red"]).includes(size) && (
<button
onClick={() => {
refreshVariant(size, "Red");
setColor("Red");
}}
className={`border-2 bg-red-600 rounded-full w-6 h-6 focus:outline-none ${
color === "Red" ? "border-black" : "border-gray-300"
}`}
></button>
)}
{Object.keys(colorSizeSlug).includes("Green") &&
Object.keys(colorSizeSlug["Green"]).includes(size) && (
<button
onClick={() => {
refreshVariant(size, "Green");
setColor("Green");
}}
className={`border-2 ml-1 bg-green-600 rounded-full w-6 h-6 focus:outline-none ${
color === "Green" ? "border-black" : "border-gray-300"
}`}
></button>
)}
{Object.keys(colorSizeSlug).includes("Black") &&
Object.keys(colorSizeSlug["Black"]).includes(size) && (
<button
onClick={() => {
refreshVariant(size, "Black");
setColor("Black");
}}
className={`border-2 ml-1 bg-black rounded-full w-6 h-6 focus:outline-none ${
color === "Black" ? "border-black" : "border-gray-300"
}`}
></button>
)}
{Object.keys(colorSizeSlug).includes("White") &&
Object.keys(colorSizeSlug["White"]).includes(size) && (
<button
onClick={() => {
refreshVariant(size, "White");
setColor("White");
}}
className={`border-2 bg-white rounded-full w-6 h-6 focus:outline-none ${
color === "White" ? "border-black" : "border-gray-300"
}`}
></button>
)}
{Object.keys(colorSizeSlug).includes("Yellow") &&
Object.keys(colorSizeSlug["Yellow"]).includes(size) && (
<button
onClick={() => {
refreshVariant(size, "Yellow");
setColor("Yellow");
}}
className={`border-2 bg-yellow-500 rounded-full w-6 h-6 focus:outline-none ${
color === "Yellow"
? "border-black"
: "border-gray-300"
}`}
></button>
)}
{Object.keys(colorSizeSlug).includes("Purple") &&
Object.keys(colorSizeSlug["Purple"]).includes(size) && (
<button
onClick={() => {
refreshVariant(size, "Purple");
setColor("Purple");
}}
className={`border-2 bg-purple-600 rounded-full w-6 h-6 focus:outline-none ${
color === "Purple"
? "border-black"
: "border-gray-300"
}`}
></button>
)}
{Object.keys(colorSizeSlug).includes("Maroon") &&
Object.keys(colorSizeSlug["Maroon"]).includes(size) && (
<button
onClick={() => {
refreshVariant(size, "Maroon");
setColor("Maroon");
}}
className={`border-2 bg-rose-700 rounded-full w-6 h-6 focus:outline-none ${
color === "Maroon"
? "border-black"
: "border-gray-300"
}`}
></button>
)}
{Object.keys(colorSizeSlug).includes("Blue") &&
Object.keys(colorSizeSlug["Blue"]).includes(size) && (
<button
onClick={() => {
refreshVariant(size, "Blue");
setColor("Blue");
}}
className={`border-2 bg-blue-500 rounded-full w-6 h-6 focus:outline-none ${
color === "Blue" ? "border-black" : "border-gray-300"
}`}
></button>
)}
</div>
<div className="flex ml-6 items-center">
<span className="mr-3">Size</span>
<div className="relative">
<select
value={size}
onChange={(e) => {
refreshVariant(e.target.value, color);
setSize(e.target.value);
}}
className="rounded border appearance-none border-gray-300 py-2 focus:outline-none focus:ring-2 focus:ring-blue-200 focus:border-blue-500 text-base pl-3 pr-10"
>
{Object.keys(colorSizeSlug[color]).includes("S") && (
<option value={"S"}>S</option>
)}
{Object.keys(colorSizeSlug[color]).includes("M") && (
<option value={"M"}>M</option>
)}
{Object.keys(colorSizeSlug[color]).includes("L") && (
<option value={"L"}>L</option>
)}
{Object.keys(colorSizeSlug[color]).includes("XL") && (
<option value={"XL"}>XL</option>
)}
{Object.keys(colorSizeSlug[color]).includes("XXL") && (
<option value={"XXL"}>XXL</option>
)}
</select>
<span className="absolute right-0 top-0 h-full w-10 text-center text-gray-600 pointer-events-none flex items-center justify-center">
<svg
fill="none"
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
className="w-4 h-4"
viewBox="0 0 24 24"
>
<path d="M6 9l6 6 6-6"></path>
</svg>
</span>
</div>
</div>
</div>
<div className="flex">
<span className="title-font font-medium text-2xl text-gray-900">
₹499
</span>
<button
onClick={() =>
addToCart(
slug,
1,
499,
"wear the chess(XL, Red)",
"XL",
"Red"
)
}
className="flex ml-auto md:ml-24 text-sm lg:text-base text-white bg-blue-500 border-0 py-2 px-4 lg:px-6 focus:outline-none hover:bg-blue-600 rounded"
>
Add to Cart
</button>
<button className="flex ml-1 md:ml-2 text-white text-sm lg:text-base bg-blue-500 border-0 py-2 px-4 lg:px-6 focus:outline-none hover:bg-blue-600 rounded">
Buy Now
</button>
<button className="rounded-full w-10 h-10 bg-gray-200 p-0 border-0 inline-flex items-center justify-center text-gray-500 ml-4 md:ml-6">
<svg
fill="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
className="w-5 h-5"
viewBox="0 0 24 24"
>
<path d="M20.84 4.61a5.5 5.5 0 00-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 00-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 000-7.78z"></path>
</svg>
</button>
</div>
<div className="pin mt-6 space-x-2 flex text-sm">
<input
type="text"
id="name"
name="name"
onChange={onChangePin}
placeholder="Enter Pincode Here"
className="w-3/5 md:w-2/5 bg-gray-100 bg-opacity-50 rounded border border-gray-300 focus:border-blue-500 focus:bg-white focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out"
/>
<button
onClick={checkservicibilty}
className="text-white bg-blue-500 border-0 py-2 px-6 focus:outline-none hover:bg-blue-600 rounded"
>
Check
</button>
</div>
{isAvailable != null ? (
isAvailable ? (
<div className="text-sm mt-4 text-green-600">
Yay ! This pincode is serviceable .
</div>
) : (
<div className="text-sm mt-4 text-red-600">
Sorry ! We do not deliver to this pincode yet .
</div>
)
) : (
<div></div>
)}
</div>
</div>
</div>
</section>
</>
);
};
// taking all the variants of a tshirt/hoodies of same title from the slug
// for eg, if slug=wear-chess-think-2, then it will give all the 'Chess-Think Tshirts'=title tshirts in variant-array
export async function getServerSideProps(context) {
if (!mongoose.connections[0].readyState) {
await mongoose.connect(process.env.MONGO_URI);
}
let product = await Product.findOne({ slug: context.query.slug });
let all_Tshirts = await Product.find({ title: product.title });
//all tshirts of same title with the given 'slug'
//console.log("all -",all_Tshirts)
let colorSizeSlug = {};
//eg: {'Red': {'XL':'wear-the-chess-king-1}}
for (let item of all_Tshirts) {
if (Object.keys(colorSizeSlug).includes(item.color)) {
colorSizeSlug[item.color][item.size] = { slug: item.slug, url: item.img };
} else {
colorSizeSlug[item.color] = {};
colorSizeSlug[item.color][item.size] = { slug: item.slug, url: item.img };
}
}
return {
props: {
all_Tshirts: JSON.parse(JSON.stringify(all_Tshirts)),
colorSizeSlug: JSON.parse(JSON.stringify(colorSizeSlug)),
}, // will be passed to the page component as props
};
}
export default Slug;
而不是使用 window.location 你需要使用 router.push
https://nextjs.org/docs/api-reference/next/router#routerpush
这里的关键是使用router push,shallow设置为true,避免页面重渲染。
const refreshVariant = (newsize, newcolor) => {
const url = `http://localhost:3000/products/${colorSizeSlug[newcolor][newsize]["slug"]}`
router.push(url, undefined, { shallow: true })
}
简介
我正在用 nextJS 设计一个电子商务平台。它由这样的 T 恤页面组成。
单击四件 T 恤中的任何一件后,我转到了 slug.js
文件中的特定 T 恤页面,页面如下所示。
这就是我面临的问题。
问题
可以看到黑色T恤页面的URL是
http://localhost:3000/products/wear-the-chess-formula-S-Black
这是正确的,但在那之后如果我 select 任何颜色和尺寸变体,比如 (Green,M)
,它不会在重新加载后反映在 URL 中。您还可以在下图中看到左上角。重新加载后我又看到了黑色 T 恤图像。
为了这个功能,我构建了以下函数。
const refreshVariant = (newsize, newcolor) => {
let url = `http://localhost:3000/products/${colorSizeSlug[newcolor][newsize]["slug"]}`;
//console.log("url = ",url, "newcolor - ",newcolor, "newsize - ", newsize)
//console.log("newvaraint -", colorSizeSlug)
window.location = url;
};
我怎么想的?
我认为点击颜色按钮和尺寸下拉选项,颜色和尺寸的值发生变化,但在重新加载后,它又回到了初始值。
现场行为
我想要什么?
我想保留这两个状态变量的值 color & size,这样每次我们 select 颜色时,相同颜色的点就会突出显示并且同样反映在 URL 中。例如,如果我 select 绿色和 M 尺寸,那么绿色点应该用边框突出显示,这个 URL 应该出现
http://localhost:3000/products/wear-the-chess-formula-M-Green
代码
负责这个的文件是slug.js
import React, { useState } from "react";
import { useRouter } from "next/router";
import mongoose from "mongoose";
import Product from "../../models/Product";
//colosizeSlug :
// {
// Black: {S: {slug: "wear-the-chess-formula-1"}},
// Blue: {M: {slug: "wear-the-chess-formula-2"}},
// Green: {L: {slug: "wear-the-chess-formula-3"}},
// Red: {XL: {slug: "wear-the-chess-think-1"} ,XXL: {slug: "wear-the-chess-think-2"}}
// }
// MY LOGS
//date - 17-4-22
//issue of setColor & setSize is resolved but now the window reload functon disabled. It is beacuse when the page reloads , the state value of color and size revert back to the its initial value & not the current value. That's why you can see the updated url is not displayed in chrome tab.
const Slug = ({ addToCart, all_Tshirts, colorSizeSlug }) => {
//console.log(all_Tshirts, colorSizeSlug);
//console.log("keys = ",Object.keys(colorSizeSlug["Red"]))
const router = useRouter();
const { slug } = router.query;
const [pin, setPin] = useState();
const [isAvailable, setIsAvailable] = useState();
const [color, setColor] = useState(all_Tshirts[0].color);
const [size, setSize] = useState(all_Tshirts[0].size);
console.log("size =", size, " color = ", color);
const checkservicibilty = async () => {
let pins = await fetch("http://localhost:3000/api/pincode");
let pinjson = await pins.json();
//console.log(pin, pinjson);
if (pinjson.includes(pin)) {
setIsAvailable(true);
//console.log("Available");
} else {
setIsAvailable(false);
//console.log("NOt");
}
};
const onChangePin = (e) => {
setPin(e.target.value);
};
const refreshVariant = (newsize, newcolor) => {
let url = `http://localhost:3000/products/${colorSizeSlug[newcolor][newsize]["slug"]}`;
//console.log("url = ",url, "newcolor - ",newcolor, "newsize - ", newsize)
//console.log("newvaraint -", colorSizeSlug)
window.location = url;
};
return (
<>
<section className="text-gray-600 body-font overflow-hidden">
<div className="container px-5 py-16 mx-auto">
<div className="lg:w-4/5 mx-auto flex flex-wrap">
<img
alt="ecommerce"
className="lg:w-1/2 w-full h-80 lg:h-[36rem] object-cover object-top rounded"
src={`${colorSizeSlug[color][size]["url"]}`}
/>
<div className="lg:w-1/2 w-full lg:pl-10 lg:py-6 mt-6 lg:mt-0">
<h2 className="text-sm title-font text-gray-500 tracking-widest">
CHESS WEAR
</h2>
<h1 className="text-gray-900 text-3xl title-font font-medium mb-1">
Men's Chess Formula T-Shirt ( L-Black )
</h1>
<div className="flex mb-4">
<span className="flex items-center">
.
.
.
<span className="text-gray-600 ml-3">4 Reviews</span>
</span>
<span className="flex ml-3 pl-3 py-2 border-l-2 border-gray-200 space-x-2s">
.
.
.
</span>
</div>
<p className="leading-relaxed">
Fam locavore kickstarter distillery. Mixtape chillwave tumeric
sriracha taximy chia microdosing tilde DIY. XOXO fam indxgo
juiceramps cornhole raw denim forage brooklyn. Everyday carry +1
seitan poutine tumeric. Gastropub blue bottle austin listicle
pour-over, neutra jean shorts keytar banjo tattooed umami
cardigan.
</p>
<div className="flex mt-6 items-center pb-5 border-b-2 border-gray-100 mb-5">
<div className="flex">
<span className="mr-3">Color</span>
{Object.keys(colorSizeSlug).includes("Red") &&
Object.keys(colorSizeSlug["Red"]).includes(size) && (
<button
onClick={() => {
refreshVariant(size, "Red");
setColor("Red");
}}
className={`border-2 bg-red-600 rounded-full w-6 h-6 focus:outline-none ${
color === "Red" ? "border-black" : "border-gray-300"
}`}
></button>
)}
{Object.keys(colorSizeSlug).includes("Green") &&
Object.keys(colorSizeSlug["Green"]).includes(size) && (
<button
onClick={() => {
refreshVariant(size, "Green");
setColor("Green");
}}
className={`border-2 ml-1 bg-green-600 rounded-full w-6 h-6 focus:outline-none ${
color === "Green" ? "border-black" : "border-gray-300"
}`}
></button>
)}
{Object.keys(colorSizeSlug).includes("Black") &&
Object.keys(colorSizeSlug["Black"]).includes(size) && (
<button
onClick={() => {
refreshVariant(size, "Black");
setColor("Black");
}}
className={`border-2 ml-1 bg-black rounded-full w-6 h-6 focus:outline-none ${
color === "Black" ? "border-black" : "border-gray-300"
}`}
></button>
)}
{Object.keys(colorSizeSlug).includes("White") &&
Object.keys(colorSizeSlug["White"]).includes(size) && (
<button
onClick={() => {
refreshVariant(size, "White");
setColor("White");
}}
className={`border-2 bg-white rounded-full w-6 h-6 focus:outline-none ${
color === "White" ? "border-black" : "border-gray-300"
}`}
></button>
)}
{Object.keys(colorSizeSlug).includes("Yellow") &&
Object.keys(colorSizeSlug["Yellow"]).includes(size) && (
<button
onClick={() => {
refreshVariant(size, "Yellow");
setColor("Yellow");
}}
className={`border-2 bg-yellow-500 rounded-full w-6 h-6 focus:outline-none ${
color === "Yellow"
? "border-black"
: "border-gray-300"
}`}
></button>
)}
{Object.keys(colorSizeSlug).includes("Purple") &&
Object.keys(colorSizeSlug["Purple"]).includes(size) && (
<button
onClick={() => {
refreshVariant(size, "Purple");
setColor("Purple");
}}
className={`border-2 bg-purple-600 rounded-full w-6 h-6 focus:outline-none ${
color === "Purple"
? "border-black"
: "border-gray-300"
}`}
></button>
)}
{Object.keys(colorSizeSlug).includes("Maroon") &&
Object.keys(colorSizeSlug["Maroon"]).includes(size) && (
<button
onClick={() => {
refreshVariant(size, "Maroon");
setColor("Maroon");
}}
className={`border-2 bg-rose-700 rounded-full w-6 h-6 focus:outline-none ${
color === "Maroon"
? "border-black"
: "border-gray-300"
}`}
></button>
)}
{Object.keys(colorSizeSlug).includes("Blue") &&
Object.keys(colorSizeSlug["Blue"]).includes(size) && (
<button
onClick={() => {
refreshVariant(size, "Blue");
setColor("Blue");
}}
className={`border-2 bg-blue-500 rounded-full w-6 h-6 focus:outline-none ${
color === "Blue" ? "border-black" : "border-gray-300"
}`}
></button>
)}
</div>
<div className="flex ml-6 items-center">
<span className="mr-3">Size</span>
<div className="relative">
<select
value={size}
onChange={(e) => {
refreshVariant(e.target.value, color);
setSize(e.target.value);
}}
className="rounded border appearance-none border-gray-300 py-2 focus:outline-none focus:ring-2 focus:ring-blue-200 focus:border-blue-500 text-base pl-3 pr-10"
>
{Object.keys(colorSizeSlug[color]).includes("S") && (
<option value={"S"}>S</option>
)}
{Object.keys(colorSizeSlug[color]).includes("M") && (
<option value={"M"}>M</option>
)}
{Object.keys(colorSizeSlug[color]).includes("L") && (
<option value={"L"}>L</option>
)}
{Object.keys(colorSizeSlug[color]).includes("XL") && (
<option value={"XL"}>XL</option>
)}
{Object.keys(colorSizeSlug[color]).includes("XXL") && (
<option value={"XXL"}>XXL</option>
)}
</select>
<span className="absolute right-0 top-0 h-full w-10 text-center text-gray-600 pointer-events-none flex items-center justify-center">
<svg
fill="none"
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
className="w-4 h-4"
viewBox="0 0 24 24"
>
<path d="M6 9l6 6 6-6"></path>
</svg>
</span>
</div>
</div>
</div>
<div className="flex">
<span className="title-font font-medium text-2xl text-gray-900">
₹499
</span>
<button
onClick={() =>
addToCart(
slug,
1,
499,
"wear the chess(XL, Red)",
"XL",
"Red"
)
}
className="flex ml-auto md:ml-24 text-sm lg:text-base text-white bg-blue-500 border-0 py-2 px-4 lg:px-6 focus:outline-none hover:bg-blue-600 rounded"
>
Add to Cart
</button>
<button className="flex ml-1 md:ml-2 text-white text-sm lg:text-base bg-blue-500 border-0 py-2 px-4 lg:px-6 focus:outline-none hover:bg-blue-600 rounded">
Buy Now
</button>
<button className="rounded-full w-10 h-10 bg-gray-200 p-0 border-0 inline-flex items-center justify-center text-gray-500 ml-4 md:ml-6">
<svg
fill="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
className="w-5 h-5"
viewBox="0 0 24 24"
>
<path d="M20.84 4.61a5.5 5.5 0 00-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 00-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 000-7.78z"></path>
</svg>
</button>
</div>
<div className="pin mt-6 space-x-2 flex text-sm">
<input
type="text"
id="name"
name="name"
onChange={onChangePin}
placeholder="Enter Pincode Here"
className="w-3/5 md:w-2/5 bg-gray-100 bg-opacity-50 rounded border border-gray-300 focus:border-blue-500 focus:bg-white focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out"
/>
<button
onClick={checkservicibilty}
className="text-white bg-blue-500 border-0 py-2 px-6 focus:outline-none hover:bg-blue-600 rounded"
>
Check
</button>
</div>
{isAvailable != null ? (
isAvailable ? (
<div className="text-sm mt-4 text-green-600">
Yay ! This pincode is serviceable .
</div>
) : (
<div className="text-sm mt-4 text-red-600">
Sorry ! We do not deliver to this pincode yet .
</div>
)
) : (
<div></div>
)}
</div>
</div>
</div>
</section>
</>
);
};
// taking all the variants of a tshirt/hoodies of same title from the slug
// for eg, if slug=wear-chess-think-2, then it will give all the 'Chess-Think Tshirts'=title tshirts in variant-array
export async function getServerSideProps(context) {
if (!mongoose.connections[0].readyState) {
await mongoose.connect(process.env.MONGO_URI);
}
let product = await Product.findOne({ slug: context.query.slug });
let all_Tshirts = await Product.find({ title: product.title });
//all tshirts of same title with the given 'slug'
//console.log("all -",all_Tshirts)
let colorSizeSlug = {};
//eg: {'Red': {'XL':'wear-the-chess-king-1}}
for (let item of all_Tshirts) {
if (Object.keys(colorSizeSlug).includes(item.color)) {
colorSizeSlug[item.color][item.size] = { slug: item.slug, url: item.img };
} else {
colorSizeSlug[item.color] = {};
colorSizeSlug[item.color][item.size] = { slug: item.slug, url: item.img };
}
}
return {
props: {
all_Tshirts: JSON.parse(JSON.stringify(all_Tshirts)),
colorSizeSlug: JSON.parse(JSON.stringify(colorSizeSlug)),
}, // will be passed to the page component as props
};
}
export default Slug;
而不是使用 window.location 你需要使用 router.push
https://nextjs.org/docs/api-reference/next/router#routerpush
这里的关键是使用router push,shallow设置为true,避免页面重渲染。
const refreshVariant = (newsize, newcolor) => {
const url = `http://localhost:3000/products/${colorSizeSlug[newcolor][newsize]["slug"]}`
router.push(url, undefined, { shallow: true })
}