as the title states I am creating a website using NextJS styled with TailwindCSS. However, there is a small and annoying issue with my code.
Here is my code below for the MainContent of the page:
"use client"
import React, {useState} from 'react';
export default function MainContent(){
const [eventTerm, setSearchTerm] = useState('');
const [zipCode, setZipCode] = useState('');
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setSearchTerm(event.currentTarget.value);
}
const handleZipChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setZipCode(event.currentTarget.value);
}
const handleSubmit = (event: React.ChangeEvent <HTMLButtonElement>) => {
event.preventDefault();
// Perform search functionality here
console.log(eventTerm);
console.log(zipCode);
}
return (
<main>
<div className = "max-w-7xl mx-5 px-5 sm:px-6 lg:px-8 my-auto py-9 mt-20 text-center">
<h1 className = "font-rowdies md:text-7xl text-white sm:text-center md:text-left my-3">Test, <br/> Test </h1>
<div className = "my-auto py-5">
<small className = "font-rowdies md:text-3xl text-white md:block md:text-left my-1 flex-wrap sm:text-2xl break-words">Test</small>
<div className="my-auto py-5 md:text-left">
<form className = "relative rounded-lg bg-transparent">
<input type="text" placeholder="Find a Service" defaultValue={eventTerm} onChange={handleChange} className="form-input mr-2 py-2 px-10 rounded-md leading-5 focus:outline-none focus:shadow-outline-indigo-500 w-800 text-center font-rowdies"/>
<input type="text" placeholder="Zip Code" defaultValue={zipCode} onChange={handleZipChange} className="form-input py-2 rounded-md leading-5 focus:outline-none focus:shadow-outline-indigo-500 w-21 text-center hidden md:inline font-rowdies"/>
<button className = "bg-gray-900 text-white ml-2 px-3 py-2 rounded-md text-l font-rowdies hover:text-secondary hover:bg-white">Lets Go!</button>
</form>
</div>
</div>
</div>
</main>
)
}
The errors I am getting in chrome are:
Error: Hydration failed because the initial UI does not match what was rendered on the server.
Warning: Did not expect server HTML to contain a in .
The issue seems to stem from this line only after refreshing the page not on the initial load
<input type="text" placeholder="Zip Code" defaultValue={zipCode} onChange={handleZipChange} className="form-input py-2 rounded-md leading-5 focus:outline-none focus:shadow-outline-indigo-500 w-21 text-center hidden md:inline font-rowdies"/>
I say this because whenever I delete this line the 2 errors go away and my website works just fine.
In addition to this, I sent my friend the file and it ran fine on his computer. Stuff that I tried included checking that my dependencies were up-to-date and clearing my cache and cookies as well as other things with my code.
Any help would be greatly appreciated. I will also add a few more code snippets as well as a directory structure image.
Thanks!
HomePage.tsx
import React, { MouseEventHandler, useState } from 'react';
import { Disclosure, Menu, Transition } from '#headlessui/react'
import '../styles/globals.css'
import MainContent from './MainContent';
export default function (){
const [isOpen, setIsOpen] = useState(false);
return (
<>
<header>
<div className = "items-center">
<nav className = "justify-between bg-secondary">
<div className = "mx-5 px-5 sm:px-6">
<div className = "relative flex items-center justify-between h-16">
<div className = "flex flex-grow-1 flex-shrink-1">
Portfolio
</div>
<div className = "hidden md:block items-end justify-end">
<div className = "ml-10 flex items-end space-x-4">
<button className = "bg-primary text-white px-3 py-2 rounded-md text-l font-rowdies hover:text-primary hover:bg-secondary">Join as a Pro</button>
Log In
Sign Up
About Us
</div>
</div>
<div className="-mr-2 flex md:hidden place-content-center">
<button
onClick={() => setIsOpen(!isOpen)}
type="button"
className="bg-gray-900 inline-flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-white hover:bg-gray-800 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-800 focus:ring-white"
aria-controls="mobile-menu"
aria-expanded="false"
>
<span className="sr-only">Open main menu</span>
{!isOpen ? (
<svg
className="block h-6 w-6"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
aria-hidden="true"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M4 6h16M4 12h16M4 18h16"
/>
</svg>
) : (
<svg
className="block h-6 w-6"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
aria-hidden="true"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M6 18L18 6M6 6l12 12"
/>
</svg>
)}
</button>
</div>
</div>
</div>
<Transition
show={isOpen}
enter="transition ease-out duration-1000 transform"
enterFrom="opacity-0 scale-95"
enterTo="opacity-100 scale-100"
leave="transition ease-in duration-75 transform"
leaveFrom="opacity-100 scale-100"
leaveTo="opacity-0 scale-95"
>
{(ref) => (
<div className="md:hidden text-center bg-secondary" id="mobile-menu">
<div ref={ref} className="px-2 pt-2 pb-3 space-y-1 sm:px-3">
Log In
Sign Up
About Us
<button className = "bg-primary text-white px-3 py-2 rounded-md text-l font-rowdies block mx-auto hover:text-primary hover:bg-secondary">Join as a Pro</button>
</div>
</div>
)}
</Transition>
</nav>
</div>
</header>
<MainContent />
</>
)
}
Page.tsx
"use client";
import Image from 'next/image'
import { Inter } from '#next/font/google'
import styles from './page.module.css'
const inter = Inter({ subsets: ['latin'] })
import { useRouter } from "next/navigation";
import Homepage from '#/components/Homepage';
import MainContent from '#/components/MainContent';
import { Main } from 'next/document';
export default function Home() {
return (
<>
<Homepage />
</>
)
}
Image of all my dependencies and their versions
When I disabled the LastPass browser extension the problem went away. LastPass injects HTML post-load that throws off the comparison between SSR and client.
I have a carousel that prints out a lists of data, 5 in total,
the issue is when I click on the next of any of the carousel buttons,
only the bottom carousel updates.
Any suggestions?
Here is my react tailwind code :
// query all available genres and for it create a listview row of the content
import { useState, useRef, useEffect } from "react";
import React from "react";
import ShowList from "./showlist.json";
import "./carousel.css";
import data from "./data.json";
export default function Genre() {
const maxScrollWidth = useRef(0);
const [currentIndex, setCurrentIndex] = useState(0);
const listCarousel = useRef(0);
const containerCarousel = useRef(0);
const movePrev = () => {
if (currentIndex > 0) {
setCurrentIndex((prevState) => prevState - 1);
}
};
const moveNext = () => {
if (
listCarousel.current !== null &&
listCarousel.current.offsetWidth * currentIndex <= maxScrollWidth.current
) {
setCurrentIndex((prevState) => prevState + 1);
}
};
const isDisabled = (direction) => {
if (direction === "prev") {
return currentIndex <= 0;
}
if (direction === "next" && listCarousel.current !== null) {
return (
listCarousel.current.offsetWidth * currentIndex >= maxScrollWidth.current
);
}
return false;
};
useEffect(() => {
if (listCarousel !== null && listCarousel.current !== null) {
listCarousel.current.scrollLeft = listCarousel.current.offsetWidth * currentIndex;
}
}, [currentIndex]);
useEffect(() => {
maxScrollWidth.current = listCarousel.current
? listCarousel.current.scrollWidth - listCarousel.current.offsetWidth
: 0;
}, []);
const DisplayData = ShowList.map((value, itemIndex) => {
let imageList = value.Shows.map((item) => {
return item;
});
return (
<section>
<div
ref={containerCarousel}
className="carousel my-12 mx-auto"
>
<h1 className="text-3xl leading-8 font-bold mb-12 text-slate-700">
{value.name}
</h1>
<div
className="relative overflow-hidden">
<div className="flex justify-between absolute top left w-full h-full">
<button
onClick={movePrev}
className="hover:bg-blue-900/75 text-white w-10 h-full text-center opacity-75 hover:opacity-100 disabled:opacity-25 disabled:cursor-not-allowed z-10 p-0 m-0 transition-all ease-in-out duration-300"
disabled={isDisabled("prev")}
>
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-12 w-20 -ml-5"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
strokeWidth={2}
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M15 19l-7-7 7-7"
/>
</svg>
<span className="sr-only">Prev</span>
</button>
<button
onClick={moveNext}
className="hover:bg-blue-900/75 text-white w-10 h-full text-center opacity-75 hover:opacity-100 disabled:opacity-25 disabled:cursor-not-allowed z-10 p-0 m-0 transition-all ease-in-out duration-300"
disabled={isDisabled("next")}
>
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-12 w-20 -ml-5"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
strokeWidth={2}
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M9 5l7 7-7 7"
/>
</svg>
<span className="sr-only">Next</span>
</button>
</div>
<div
ref={listCarousel}
className="carousel-container relative flex gap-1 overflow-hidden scroll-smooth snap-x snap-mandatory touch-pan-x z-0"
>
{imageList.map((img, index) => {
return (
<ul>
<li
key={index}
className="carousel-item text-center relative w-64 h-64 snap-start"
>
<a
href={img.link}
className="h-full w-full aspect-square block bg-origin-padding bg-left-top bg-cover bg-no-repeat z-0"
style={{ backgroundImage: `url(${img.image || ""})` }}
>
<img
src={img.image || ""}
alt={img.title}
className="w-full rounded aspect-square hidden"
/>
</a>
<a
href={img.link}
className="h-full w-full aspect-square block absolute top-0 left-0 transition-opacity duration-300 opacity-0 hover:opacity-100 bg-blue-800/75 z-10"
>
<h3 className="text-white py-6 px-3 mx-auto text-xl">
{img.title}
</h3>
</a>
</li>
</ul>
);
})}
</div>
</div>
</div>
</section>
);
});
return <div>{DisplayData}</div>;
}
here is my data json file:
https://drive.google.com/file/d/1G0wInErDa2bUHGjn-TNDfTVXJru0QlaY/view?usp=sharing
I recently came across this carousel Tailwind component (https://codesandbox.io/s/react-multi-item-carousel-uvmchp?file=/src/carousel.jsx).
I wanted the carousel items to enlargen on hover, so I made a change (namely adding hover:scale-125 transform-gpu transition duration-150 ease-in-out and removing overflow-hidden), but in doing so the left and right arrows of the carousel no longer work.
How can I fix this?
My code is here: https://codesandbox.io/s/react-multi-item-carousel-forked-jebmii?file=/src/carousel.jsx:0-4494
import { useState, useRef, useEffect } from "react";
import data from "./data.json";
const CollectionCarousel = () => {
const maxScrollWidth = useRef(0);
const [currentIndex, setCurrentIndex] = useState(0);
const carousel = useRef(null);
const movePrev = () => {
if (currentIndex > 0) {
setCurrentIndex((prevState) => prevState - 1);
}
};
const moveNext = () => {
if (carousel.current.offsetWidth * currentIndex <= maxScrollWidth.current) {
setCurrentIndex((prevState) => prevState + 1);
}
};
const isDisabled = (direction) => {
if (direction === "prev") {
return currentIndex <= 0;
}
if (direction === "next" && carousel.current !== null) {
return (
carousel.current.offsetWidth * currentIndex >= maxScrollWidth.current
);
}
return false;
};
useEffect(() => {
if (carousel !== null && carousel.current !== null) {
carousel.current.scrollLeft = carousel.current.offsetWidth * currentIndex;
}
}, [currentIndex]);
useEffect(() => {
maxScrollWidth.current = carousel.current
? carousel.current.scrollWidth - carousel.current.offsetWidth
: 0;
}, []);
return (
<div className="carousel my-12 mx-auto">
<div className="relative">
<div className="flex justify-between absolute top left w-full h-full">
<button
onClick={movePrev}
className="hover:bg-blue-900/75 text-white w-10 h-full text-center opacity-75 hover:opacity-100
disabled:opacity-25 disabled:cursor-not-allowed z-10 p-0 m-0 transition-all ease-in-out duration-300"
disabled={isDisabled("prev")}
>
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-12 w-20 -ml-5"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
strokeWidth={2}
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M15 19l-7-7 7-7"
/>
</svg>
<span className="sr-only">Prev</span>
</button>
<button
onClick={moveNext}
className="hover:bg-blue-900/75 text-white w-10 h-full text-center opacity-75 hover:opacity-100
disabled:opacity-25 disabled:cursor-not-allowed z-10 p-0 m-0 transition-all ease-in-out duration-300"
disabled={isDisabled("next")}
>
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-12 w-20 -ml-5"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
strokeWidth={2}
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M9 5l7 7-7 7"
/>
</svg>
<span className="sr-only">Next</span>
</button>
</div>
<div
ref={carousel}
className="carousel-container relative flex gap-1 scroll-smooth snap-x snap-mandatory touch-pan-x z-0"
>
{data.resources.map((resource, index) => {
return (
<div
key={index}
className="carousel-item text-center relative w-64 h-64 snap-start hover:scale-125 transform-gpu
transition duration-150 ease-in-out"
>
<a
href={resource.link}
className="h-full w-full aspect-square block bg-origin-padding bg-left-top bg-cover bg-no-repeat z-0"
style={{ backgroundImage: `url(${resource.imageUrl || ""})` }}
>
<img
src={resource.imageUrl || ""}
alt={resource.title}
className="w-full aspect-square hidden"
/>
</a>
<a
href={resource.link}
className="h-full w-full aspect-square block absolute top-0 left-0 transition-opacity
duration-300 opacity-0 hover:opacity-100 bg-blue-800/75 z-10"
>
<h3 className="text-white py-6 px-3 mx-auto text-xl">
{resource.title}
</h3>
</a>
</div>
);
})}
</div>
</div>
</div>
);
};
export default CollectionCarousel;
Intro
I am designing an e-commerce platform in nextJS. It consists of Tshirts page like this .
After clicking any of the four t-shirts, i went to that particular t-shirt page in slug.js file, where the page looks like this.
This is where I am facing issue.
Issue
As you can see that the URL of the black t-shirt page is
http://localhost:3000/products/wear-the-chess-formula-S-Black
which is correct, but after that if I select any of the color and size variant, say (Green,M), It does not get reflected in the URL after the reload . You can also see the top-left on the image below. Also after the reload I see the black t-shirt image again.
For this functionality , I had built the following function.
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;
};
What I thought?
I think that clicking the colour button & size dropdown option , the value of color&size changes but then after reloads, it again goes to its initial value.
Live Behaviour
what i want?
I want to retain the values of these two state variables color & size, so that every time we select the color, the same color dot get highlighted and same gets reflected in URL. For example if I select the Green color and M size, then Green color dot should get highlighted with border and this URL should come
http://localhost:3000/products/wear-the-chess-formula-M-Green
code
The file responsible for this is 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;
The key here is to use router push with shallow set as true, in order to avoid page rerendering.
const refreshVariant = (newsize, newcolor) => {
const url = `http://localhost:3000/products/${colorSizeSlug[newcolor][newsize]["slug"]}`
router.push(url, undefined, { shallow: true })
}
Instead of using window.location you need to use router.push
https://nextjs.org/docs/api-reference/next/router#routerpush
I Want if I click on the edit icon the text will appear in input and I can edit it and when I submit it will edit not created again.
I did the click on edit icon the text will appear in input but when I submit its created as new, so how can I do that?
here is a gif of what I have i want in submit will be updated
app.js
function App() {
const [tasks, setTask]=useState([])
const [title, setTitle]=useState("")
const [changeTasks , setChangeTasks ] = useState(false)
const [edit, setEdit]=useState(false)
useEffect(() => {
axios.get('/tasks')
.then(data=>setTask(data.data))
.catch(err => console.log(err))
}, [changeTasks]);
const addTask = (e) =>{
e.preventDefault()
axios.post('/tasks/create', {title:title, completed: true})
.then(data => setChangeTasks(pre => !pre))
.catch(err => console.log(err))
// to empty input after submit
setTitle("")
if(edit === true){
// do axios.put, but its in other component how could i do that
}
}
return (
<div className="relative flex min-h-screen bg-gray-200 flex-col justify-center overflow-hidden bg-gray-50 py-6 sm:py-12">
<h1 className="flex justify-center p-4 md:p-0 mx-px md:mt-4 md:mb-3 text-center font-extrabold text-transparent text-8xl bg-clip-text bg-gradient-to-r from-purple-800 to-pink-300">
To Do List
</h1>
<div className="relative bg-white px-6 pt-10 pb-8 shadow-xl ring-1 ring-gray-900/5 sm:mx-auto sm:max-w-lg sm:rounded-lg sm:px-10">
<div className="p-2">
<figure className="mb-4">
<blockquote className="italic font-extralight text-slate-700 mb-5">
<q> To-Do lists help us break life into small steps. </q>
<figcaption className="ml-5 text-sm">—Randy Pausch</figcaption>
</blockquote>
</figure>
<form onSubmit={addTask} >
<input
onChange={({target})=>{
setTitle(target.value)
}}
type="text"
className="p-3 mt-2 mb-4 w-full bg-slate-200 rounded border-2 border-slate-200 focus:border-slate-600 focus:outline-none placeholder:italic"
placeholder="Add Your Task..."
value={title}
/>
</form>
<ul>
{tasks.map(ele => <Task {...ele} setChangeTasks = {setChangeTasks} setTitle={setTitle} setEdit={ setEdit}/>)}
</ul>
</div>
</div>
</div>
);
}
export default App;
Task.jsx
import axios from 'axios'
const Task = ({title, id, completed,setChangeTasks, setTitle, setEdit}) => {
const updateTask =()=>{
axios.put(`/tasks/${id}/update`,{title:title,completed : ! completed })
.then(data => setChangeTasks(pre => !pre))
.catch(err => console.log(err))
}
const deleteTask =()=>{
axios.delete(`/tasks/${id}/delete`)
.then(data => setChangeTasks(pre => !pre))
.catch(err => console.log(err))
}
const editTask =()=>{
axios.put(`/tasks/${id}/update`,{title:title})
.then(data => setChangeTasks())
.catch(err => console.log(err))
setEdit(true)
setTitle(title)
}
return (
<li>
<div className="mt-7 ml-3 flex justify-between">
<label className="inline-flex items-center ">
<input
onClick={updateTask}
type="checkbox"
className=" h-6 w-5 accent-violet-200 hover:accent-violet-200 border-0 rounded-md focus:ring-0"
/>
<span className={ completed ? "ml-4 text-lg" : "ml-4 text-lg line-through"} >{title}</span>
</label>
<div className="">
<button onClick={deleteTask} className="mx-4 text-purple-700 hover:text-white hover:bg-purple-600 p-1 px-2 rounded">
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-5 w-5"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
strokeWidth="2"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"
/>
</svg>
</button>
<button onClick={editTask} class=" text-purple-700 hover:text-white hover:bg-purple-600 p-1 px-2 rounded">
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-5 w-5"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
stroke-width="2"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z"
/>
</svg>
</button>
</div>
</div>
</li>
)
}
export default Task