Reactjs => Dynamic active menu change color - javascript

I'm having a problem here when I want to make dynamic color changes when the user wants to click on the menu in the sidebar.
So, when the user wants to move the page from /building to /street, then the user will click the "street" menu and hopefully the street menu will change color like the building menu which changes color to red when the menu is active.
however, when I made it not as I expected and the result is like the image below.
Maybe the masters can help me. Thank you very much
Sidebar.jsx
import React from "react";
import { useState } from "react";
import { BiBuildingHouse } from "react-icons/bi";
import { FaRoad } from "react-icons/fa";
import { Link, NavLink } from "react-router-dom";
const Sidebar = () => {
const [activeMenu, setActiveMenu] = useState(false);
return (
<div className='w-[16rem] h-[72rem] bg-[#FFFFFF] px-5 py-3 md:px-8 md:py-5 drop-shadow-xl"'>
<h1 className="text-[#92929D] font-semibold ml-3">DASHBOARD</h1>
<NavLink
to="/try/building"
className={
activeMenu === "/try/building"
? "mr-6 mt-4 w-[12rem] h-[4rem] bg-red-500 text-white py-3 md:px-8 md:py-5 rounded-2xl drop-shadow-xl cursor-pointer"
: "mr-6 mt-4 text-black py-3 md:px-8 md:py-5 rounded-2xl drop-shadow-xl cursor-pointer"
}
onClick={() => {
setActiveMenu("/try/building");
}}
active={activeMenu}
>
<div className="mr-6 mt-4 w-[12rem] h-[4rem] bg-red-500 py-3 md:px-8 md:py-5 rounded-2xl drop-shadow-xl cursor-pointer">
<div className="inline-flex gap-4 items-center">
<BiBuildingHouse size={25} className="text-white" />
<h1 className="text-white">Building</h1>
</div>
</div>
</NavLink>
<Link
to="/try/street"
className={
activeMenu === "/try/street"
? "mr-6 mt-4 w-[12rem] h-[4rem] bg-red-500 text-white py-3 md:px-8 md:py-5 rounded-2xl drop-shadow-xl cursor-pointer"
: "mr-6 mt-4 text-black py-3 md:px-8 md:py-5 rounded-2xl drop-shadow-xl cursor-pointer"
}
onClick={() => {
setActiveMenu("/try/street");
}}
active={activeMenu}
>
<div className="mr-6 w-[12rem] h-[4rem] py-3 md:px-8 md:py-5 rounded-2xl drop-shadow-xl cursor-pointer">
<div className="inline-flex gap-4 items-center">
<FaRoad size={25} className="text-[#92929D]" />
<h1 className="text-black">Street</h1>
</div>
</div>
</Link>
</div>
);
};
export default Sidebar;

You can't use useState() like that, you either have one state for text or for boolean.
You need to use it like this:
const [activeMenu, setActiveMenu] = useState(false);
const [activeLink, setActiveLink] = useState("");
Secondly, you can't use activeMenu for both links, you don't need this active={activeMenu} at all.
Please use simple CSS, whatever library you use must have a classname:active,
or simply add:
.my_className {
background: white;
color: black;
}
.my_className:active, .my_className:selected, .my_className:hover {
background: red;
}
then add the my_className to every menu item.
more easy way you can use ant.desgin library, very straight forward and easy to implement.

The main issue with the current code is that all links are attempting to use the same activeMenu state. Neither the NavLink nor Link components consume an active prop though.
The NavLink component already applies an active class by default, and can otherwise already handle the logic you are trying to do manually. The className prop can also take a callback function that is passed an isActive prop when it matches the current URL pathname.
Example:
const Sidebar = () => {
return (
<div className='w-[16rem] h-[72rem] bg-[#FFFFFF] px-5 py-3 md:px-8 md:py-5 drop-shadow-xl"'>
<h1 className="text-[#92929D] font-semibold ml-3">DASHBOARD</h1>
<NavLink
to="/try/building"
className={({ isActive }) =>
isActive
? "mr-6 mt-4 w-[12rem] h-[4rem] bg-red-500 text-white py-3 md:px-8 md:py-5 rounded-2xl drop-shadow-xl cursor-pointer"
: "mr-6 mt-4 text-black py-3 md:px-8 md:py-5 rounded-2xl drop-shadow-xl cursor-pointer"
}
>
<div className="mr-6 mt-4 w-[12rem] h-[4rem] bg-red-500 py-3 md:px-8 md:py-5 rounded-2xl drop-shadow-xl cursor-pointer">
<div className="inline-flex gap-4 items-center">
<BiBuildingHouse size={25} className="text-white" />
<h1 className="text-white">Building</h1>
</div>
</div>
</NavLink>
<NavLink
to="/try/street"
className={({ isActive }) =>
isActive
? "mr-6 mt-4 w-[12rem] h-[4rem] bg-red-500 text-white py-3 md:px-8 md:py-5 rounded-2xl drop-shadow-xl cursor-pointer"
: "mr-6 mt-4 text-black py-3 md:px-8 md:py-5 rounded-2xl drop-shadow-xl cursor-pointer"
}
>
<div className="mr-6 w-[12rem] h-[4rem] py-3 md:px-8 md:py-5 rounded-2xl drop-shadow-xl cursor-pointer">
<div className="inline-flex gap-4 items-center">
<FaRoad size={25} className="text-[#92929D]" />
<h1 className="text-black">Street</h1>
</div>
</div>
</Link>
</div>
);
};

Related

how to apply condition on fetching data from api?

currently i am using fakestoreapi, here i am passing category parameter to fetch data from api.
const res = await fetch(`https://fakestoreapi.com/products/${category}`)
and displaying products from fetched data
{products.map((product, index) => (
<div key={product.id} className="w-full max-w-sm text-black rounded-lg shadow-md bg-white justify-bitween cursor-pointer ">
<Link to={`/${product.category}/${product.id}`}>
<img className="p-2 rounded-t-lg w-full h-[150px] md:h-[200px] object-contain" src={product.image} alt="productimage" />
</Link>
<div className="px-5 pb-2">
<Link to={`/${product.category}/${product.id}`}>
<h5 className="text-[15px] font-semibold tracking-tight text-gray-900 hover:text-blue-700">{product.title.slice(0, 30)}...</h5>
</Link>
<div className="flex items-center justify-between py-4">
<span className="text-2xl sm:text-2xl font-bold text-gray-900 ">${product.price}</span>
<button className="hidden sm:block text-white bg-indigo-500 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-indigo-500 dark:hover:bg-blue-800 dark:focus:ring-blue-800" onClick={() => addToCart(product)}>Add to cart</button>
</div>
</div>
</div>
))}
but now i do not want to display all product of that category how to do that?
how to show selective or remove unwanted product details fetched from that id?
Fakestore API can receive a limit query parameter :
fetch('https://fakestoreapi.com/products/category/jewelery?limit=2')
.then(res=>res.json())
.then(json=>console.log(json))
You can also use limit(Number) and sort(asc|desc) as a query string to get your ideal results
https://fakestoreapi.com/docs

Navbar component works in normal cases but breaks incase of getstatic props

I am trying to make a page with getstaticprops but I am unable to include my navbar component in it as console screams out element type is invalid. I can use the same navbar component during normal page rendering without static or server props. my staticprops page
import {Navbar} from "../components/schema/Navbar"
export default function Dope({users}) {
console.log(users)
return (
<div>
{/* <Navbar /> */}
<main>
<div>
{users.length === 0 ? (
<h2>No users added</h2>
) : (
users.map((user, i) => (
<h1 key={i}>{user}</h1>
))
)}
</div>
</main>
</div>
)
}
export async function getStaticProps(ctx) {
// get the current environment
let dev = process.env.NODE_ENV !== 'production';
let { DEV_URL, PROD_URL } = process.env;
// request posts from api
let response = await fetch(`${dev ? DEV_URL : PROD_URL}/api/users`);
// extract the data
let data = await response.json();
return {
props : {
users : data['message']
}
}
}
my navbar component is too big to fit in here but it returns a regular navbar without any fetch operations and uses tailwindcss where as I did not make use of tailwind to style this page yet. can this be the reason? although I feel it isn't
the api endpoint works fine as well.
Edit:
my navbar is using Popover(panel, button, group), transition elements from headlessui
and Fragment from react
import { Fragment } from 'react'
import { Popover, Transition } from '#headlessui/react'
import {
BookmarkAltIcon,
CalendarIcon,
ChartBarIcon,
CursorClickIcon,
MenuIcon,
RefreshIcon,
ShieldCheckIcon,
SupportIcon,
ViewGridIcon,
XIcon,
} from '#heroicons/react/outline'
import { ChevronDownIcon } from '#heroicons/react/solid'
const features = [
{
name: 'Airdrops',
href: '#',
description: 'Get a better understanding of where your traffic is coming from.',
icon: ChartBarIcon,
},
{
name: 'Updates',
href: '#',
description: 'Speak directly to your customers in a more meaningful way.',
icon: CursorClickIcon,
},
{ name: 'Airdrop Tracer', href: '#', description: "Your customers' data will be safe and secure.", icon: ShieldCheckIcon },
{
name: 'FAQ',
href: '#',
description: "Connect with third-party tools that you're already using.",
icon: ViewGridIcon,
},
{
name: 'About',
href: '#',
description: 'Build strategic funnels that will drive your customers to convert',
icon: RefreshIcon,
},
]
const resources = [
{
name: 'Help Center',
description: 'Get all of your questions answered in our forums or contact support.',
href: '#',
icon: SupportIcon,
},
{
name: 'Guides',
description: 'Learn how to maximize our platform to get the most out of it.',
href: '#',
icon: BookmarkAltIcon,
},
{
name: 'Events',
description: 'See what meet-ups and other events we might be planning near you.',
href: '#',
icon: CalendarIcon,
},
{ name: 'Security', description: 'Understand how we take your privacy seriously.', href: '#', icon: ShieldCheckIcon },
]
function classNames(...classes) {
return classes.filter(Boolean).join(' ')
}
export default function Navbar() {
return (
<div className="relative bg-gray-50">
<Popover className="relative bg-white shadow">
<div className="max-w-7xl mx-auto px-4 sm:px-6">
<div className="flex justify-between items-center py-6 md:justify-start md:space-x-10">
<div className="flex justify-start lg:w-0 lg:flex-1">
<a href="#">
<span className="sr-only">Workflow</span>
<img
className="h-8 w-auto sm:h-10"
src="https://tailwindui.com/img/logos/workflow-mark-indigo-600.svg"
alt=""
/>
</a>
</div>
<div className="-mr-2 -my-2 md:hidden">
<Popover.Button className="bg-white rounded-md p-2 inline-flex items-center justify-center text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-indigo-500">
<span className="sr-only">Open menu</span>
<MenuIcon className="h-6 w-6" aria-hidden="true" />
</Popover.Button>
</div>
<Popover.Group as="nav" className="hidden md:flex space-x-10">
<a href="#" className="text-base font-medium text-gray-500 hover:text-gray-900">
Airdrops
</a>
<a href="#" className="text-base font-medium text-gray-500 hover:text-gray-900">
Potential Airdrops
</a>
<a href="#" className="text-base font-medium text-gray-500 hover:text-gray-900">
Airdrop Tracer
</a>
<Popover className="relative">
{({ open }) => (
<>
<Popover.Button
className={classNames(
open ? 'text-gray-900' : 'text-gray-500',
'group bg-white rounded-md inline-flex items-center text-base font-medium hover:text-gray-900 focus:outline-none'
)}
>
<span>More</span>
<ChevronDownIcon
className={classNames(
open ? 'text-gray-600' : 'text-gray-400',
'ml-1 mt-2 h-5 w-5 group-hover:text-gray-500'
)}
aria-hidden="true"
/>
</Popover.Button>
<Transition
as={Fragment}
enter="transition ease-out duration-200"
enterFrom="opacity-0 translate-y-1"
enterTo="opacity-100 translate-y-0"
leave="transition ease-in duration-150"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 translate-y-1"
>
<Popover.Panel className="absolute left-1/2 z-10 transform -translate-x-1/2 mt-3 px-2 w-screen max-w-md sm:px-0">
<div className="rounded-lg shadow-lg ring-1 ring-black ring-opacity-5 overflow-hidden">
<div className="relative grid gap-6 bg-white px-5 py-6 sm:gap-8 sm:p-8">
{resources.map((item) => (
<a
key={item.name}
href={item.href}
className="-m-3 p-3 flex items-start rounded-lg hover:bg-gray-50"
>
<item.icon className="flex-shrink-0 h-6 w-6 text-indigo-600" aria-hidden="true" />
<div className="ml-4">
<p className="text-base font-medium text-gray-900">{item.name}</p>
<p className="mt-1 text-sm text-gray-500">{item.description}</p>
</div>
</a>
))}
</div>
</div>
</Popover.Panel>
</Transition>
</>
)}
</Popover>
</Popover.Group>
<div className="hidden md:flex items-center justify-end md:flex-1 lg:w-0">
<a href="#" className="whitespace-nowrap text-base font-medium text-gray-500 hover:text-gray-900">
Sign in
</a>
<a
href="#"
className="ml-8 whitespace-nowrap inline-flex items-center justify-center px-4 py-2 border border-transparent rounded-md shadow-sm text-base font-medium text-white bg-indigo-600 hover:bg-indigo-700"
>
Sign up
</a>
</div>
</div>
</div>
<Transition
as={Fragment}
enter="duration-200 ease-out"
enterFrom="opacity-0 scale-95"
enterTo="opacity-100 scale-100"
leave="duration-100 ease-in"
leaveFrom="opacity-100 scale-100"
leaveTo="opacity-0 scale-95"
>
<Popover.Panel
focus
className="absolute top-0 inset-x-0 z-10 p-2 transition transform origin-top-right md:hidden"
>
<div className="rounded-lg shadow-lg ring-1 ring-black ring-opacity-5 bg-white divide-y-2 divide-gray-50">
<div className="pt-5 pb-6 px-5">
<div className="flex items-center justify-between">
<div>
<img
className="h-8 w-auto"
src="https://tailwindui.com/img/logos/workflow-mark-indigo-600.svg"
alt="Workflow"
/>
</div>
<div className="-mr-2">
<Popover.Button className="bg-white rounded-md p-2 inline-flex items-center justify-center text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-indigo-500">
<span className="sr-only">Close menu</span>
<XIcon className="h-6 w-6" aria-hidden="true" />
</Popover.Button>
</div>
</div>
<div className="mt-6">
<nav className="grid gap-y-8">
{features.map((item) => (
<a
key={item.name}
href={item.href}
className="-m-3 p-3 flex items-center rounded-md hover:bg-gray-50"
>
<item.icon className="flex-shrink-0 h-6 w-6 text-indigo-600" aria-hidden="true" />
<span className="ml-3 text-base font-medium text-gray-900">{item.name}</span>
</a>
))}
</nav>
</div>
</div>
<div className="py-6 px-5 space-y-6">
<div>
<a
href="#"
className="w-full flex items-center justify-center px-4 py-2 border border-transparent rounded-md shadow-sm text-base font-medium text-white bg-indigo-600 hover:bg-indigo-700"
>
Sign up
</a>
<p className="mt-6 text-center text-base font-medium text-gray-500">
Existing customer?
<a href="#" className="text-indigo-600 hover:text-indigo-500">
Sign in
</a>
</p>
</div>
</div>
</div>
</Popover.Panel>
</Transition>
</Popover>
</div>
)
Could you show us the Navbar code as well? can't really say what's going wrong without taking a look at the code.
Edit:
The problem is, when you import the Navbar component you are using a named import (an import with curly braces), and your Navbar component
is a default export, so you should use a default import like so:
import Navbar from "../components/schema/Navbar"
notice there are no curly braces.
check out this blog post -https://vhudyma-blog.eu/2020-09-27-default-vs-named-export-what-is-the-difference/
I was importing the function Navbar in a wrong manner. I was destructuring Navbar during import where as it should be a normal import

react modal unable to open

i am trying to use the headless ui modal but i am trying to launch this modal.js from my home.js file.
so in my home.js file i have something like this
function Home() {
const [isOpen, setIsOpen] = useState(false)
const resultCKDArr = Object.values(responseData.ckd).map((item, i)=>
<section class="text-gray-600 body-font overflow-hidden">
<div class="container px-5 py-10 mx-auto">
<button onClick={() => setIsOpen(!isOpen)} class="flex ml-auto text-white bg-indigo-500 border-0 py-2 px-6 focus:outline-none hover:bg-indigo-600 rounded">Buy List</button>
</div>
<Modal isOpen={isOpen} setIsOpen={setIsOpen} />
</section>
)
return (
<>
{resultCKDArr }
</>
);
export default Home;
and this is my modal.js copy from headless ui modal as example to test
import React, { Fragment } from "react";
import { Dialog, Transition } from '#headlessui/react'
export default function Modal( props ) {
const { isOpen, setIsOpen } = props
return (
<Transition appear show={isOpen} as={Fragment}>
<Dialog as="div" className="relative z-10" onClose={setIsOpen}>
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="fixed inset-0 bg-black bg-opacity-25" />
</Transition.Child>
<div className="fixed inset-0 overflow-y-auto">
<div className="flex min-h-full items-center justify-center p-4 text-center">
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0 scale-95"
enterTo="opacity-100 scale-100"
leave="ease-in duration-200"
leaveFrom="opacity-100 scale-100"
leaveTo="opacity-0 scale-95"
>
<Dialog.Panel className="w-full max-w-md transform overflow-hidden rounded-2xl bg-white p-6 text-left align-middle shadow-xl transition-all">
<Dialog.Title
as="h3"
className="text-lg font-medium leading-6 text-gray-900"
>
Payment successful
</Dialog.Title>
<div className="mt-2">
<p className="text-sm text-gray-500">
Your payment has been successfully submitted. We’ve sent
you an email with all of the details of your order.
</p>
</div>
<div className="mt-4">
<button
type="button"
className="inline-flex justify-center rounded-md border border-transparent bg-blue-100 px-4 py-2 text-sm font-medium text-blue-900 hover:bg-blue-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2"
onClick={setIsOpen}
>
Got it, thanks!
</button>
</div>
</Dialog.Panel>
</Transition.Child>
</div>
</div>
</Dialog>
</Transition>
)
};
maybe this is the error i saw in console
Warning: React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
when i click on the button, i nothing happen, no modal pop out.
In my case there was an error with Dialog.Panel component. Try changing it to a div.

Next.js keeps throwing error params is undefined

I have successfully connected my custom server using Node.js and Express.js with Next.js. I'm trying to fetch a car by its id whenever I click it among other cars, so I can have that particular car only. But I keep getting an error saying params is undefined even though I get the id at the back of my link whenever I click on the single car in the browser. I've tried fetching the data using thunder client and everything works fine. I believe something is wrong with my frontend logic.
This is where I'm trying to fetch the data with the id
<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>
import Layout from "#/components/Layout";
import Image from "next/image";
import Link from "next/link";
import { useEffect, useState } from "react";
import Authorization from "#/HOC/Authorization";
import axios from "axios";
const Car = () => {
const [data, setData] = useState("");
const oneCar = async (params) => {
const { id } = params;
const res = await axios.get(`http://localhost:5000/one-car/${id}`);
setData(res.data);
if (res.status !== 200) {
console.log(res.status);
}
};
useEffect(() => {
oneCar();
}, []);
return (
<Layout>
{data && (
<div className="flex flex-col w-11/12 mx-auto mt-8 justify-center bg-blue-200 rounded-lg shadow">
<div className="flex w-full justify-center mt-6 px-4 mx-auto box-shadow-lg h-2/4 relative">
<Image
src="/assets/images/d17.jpg"
alt="shopping image"
className="mx-auto flex rounded-lg inset-0 w-full h-2/4 object-cover"
width={1000}
height={500}
/>
</div>
<form className="flex-auto p-6">
<div className="flex flex-wrap">
<h1 className="flex-auto text-xl font-semibold text-gray-800">
{data.carName}
</h1>
<div className="text-xl font-semibold text-gray-700 ">
{data.carPrice}
</div>
<div className="w-full flex-none text-sm font-medium text-gray-500 mt-2">
In stock
</div>
</div>
<div className="flex items-baseline mt-4 mb-6 text-gray-800 ">
<Link
href="#"
className="ml-auto hidden md:block text-sm text-gray-500 underline"
>
Size Guide
</Link>
</div>
<div className="flex mb-4 text-sm font-medium">
<button
type="button"
className="py-2 px-4 bg-blue-700 hover:bg-blue-800 focus:ring-indigo-500 focus:ring-offset-indigo-200 text-white w-full sm:w-1/4 transition ease-in duration-200 text-center text-base font-semibold shadow-md focus:outline-none focus:ring-2 focus:ring-offset-2 mx-auto rounded-lg "
>
Buy now
</button>
</div>
<p className="text-sm text-gray-500 text-center ">
Free shipping on all continental US orders.
</p>
</form>
</div>
)}
</Layout>
);
};
export default Authorization(Car);
This is where I fetch all cars and makes the id a parameter to the link address
<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>
import Image from "next/image";
import Layout from "#/components/Layout";
import Pagination from "#/components/Pagination";
import { GiBinoculars } from "react-icons/gi";
import { useGetAllCarsQuery } from "#/store/ReduxStore/getAllCarsApi";
import Link from "next/link";
const Market = () => {
//I use RTK Query to fetch the data, and It was successfully fetched
const { data, isLoading, error } = useGetAllCarsQuery();
return (
<Layout>
<div className="2xl:container 2xl:mx-auto">
<div className=" py-3 lg:px-20 md:px-6 px-4">
<div className=" flex justify-center mt-3 items-center">
<div className=" flex space-x-3 justify-center items-center">
<span className="bg-blue-800 px-4 py-2 rounded-md text-2xl text-white">
<GiBinoculars />
</span>
<input
type="search"
className="border-b-2 w-9/12 border-gray-700 -mb-3 leading-5 text-lg p-2 focus:outline-none"
placeholder="Search for cars here..."
/>
</div>
</div>
<hr className=" w-full bg-gray-200 my-6" />
<div className=" grid lg:grid-cols-4 sm:grid-cols-2 grid-cols-1 lg:gap-y-12 lg:gap-x-8 sm:gap-y-10 sm:gap-x-6 gap-y-6 lg:mt-12 mt-10">
{data?.map((cars, i) => (
<Link
key={i}
href="/[id]"
as={`${cars._id}`}
//I insert the id here
className="relative"
passHref
>
<div>
<div className=" relative group">
<div className="caroverlay"></div>
<Image
width={600}
height={400}
className="rounded-md w-full"
src="/assets/images/d17.jpg"
alt="A girl Posing Img"
/>
<div className=" absolute bottom-0 p-8 w-full opacity-0 group-hover:opacity-100 z-20">
<button className="text-base font-bold leading-4 text-gray-600 hover:bg-gray-300 hover:text-gray-700 bg-white py-3 w-full">
Add to your garage
</button>
<button className=" bg-transparent text-base font-bold leading-4 border-2 hover:bg-gray-300 hover:text-gray-700 border-white py-3 w-full mt-2 text-white">
View Car
</button>
</div>
</div>
<p className=" text-xl leading-5 text-gray-600 md:mt-6 mt-4">
{cars.carName}
</p>
<p className=" font-semibold text-xl leading-5 text-gray-800 mt-4">
<span>$</span> {cars.carPrice}
</p>
</div>
</Link>
))}
</div>
{/* _______________________________________________________ */}
<Pagination />
{/* _______________________________________________________ */}
</div>
</div>
</Layout>
);
};
export default Market;
Here is my backend logic
<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>
const router = require("express").Router();
const auth = require("../../middleware/auth");
const Car = require("../../Model/CarSchema");
router.get("/onecar/:id", auth, async (req, res) => {
try {
const car = await Car.findById(req.params.id);
res.status(200).json(car);
} catch (err) {
res.status(500).json({ msg: "Server Error" });
}
});
module.exports = router;
To access id in nextjs. I imported useRouter from next/router. Then I const router = useRouter(). Then const {id} = router.query

useState being set to false but ternary operator not working

I have a simple state let [isOpen, setIsOpen] = useState(false);
It doesn't when it gets back set to false it the ternary operator doesn't seem to be doing anything.
export default function ShowContact(props) {
let [isOpen, setIsOpen] = useState(false);
...
function closeButtons() {
setIsOpen(false);
console.log(isOpen);
}
I have the following
{!isOpen ? <span>TRUE</span> : <span>FALSE</span>}
{!isOpen ? (
<div>
<div className="mt-6 flex flex-col">
<button className="mb-1 rounded bg-blue-500 px-4 py-3 capitalize text-white duration-100 ease-in-out hover:bg-blue-700">
<span className="text-center">edit</span>
</button>
<button
className="rounded bg-red-500 px-4 py-3 capitalize text-white duration-100 ease-in-out hover:bg-red-700"
onClick={closeButtons}
>
<span className="text-center tracking-wide">delete</span>
</button>
</div>
</div>
) : (
<div>
<div className="mt-6 flex flex-col">
<button className="mb-1 rounded bg-green-500 px-4 py-3 capitalize text-white duration-100 ease-in-out hover:bg-green-700">
<span className="text-center">edit</span>
</button>
<button
className="rounded bg-red-500 px-4 py-3 capitalize text-white duration-100 ease-in-out hover:bg-red-700"
onClick={deleteContact}
>
<span className="text-center tracking-wide">yes delete</span>
</button>
</div>
</div>
)}
the {isOpen ? <span>TRUE</span> : <span>FALSE</span>} is simple to test that isOpen is being set to false. Which is does as I have checked the console.
Still though the ternary isn't changing. This is very annoying as it was working earlier and something has changed I am not sure if this is an effect from other components, but I can not see why?
But I know the buttons are working as the deleteContact function is working and the isOpen is getting set to false
I am complete miffed about this, any suggestions would be welcome.
import { useEffect, useState } from 'react';
export default function ShowContact(props) {
let [isOpen, setIsOpen] = useState(false);
let [contact, setContact] = useState({});
// delete contact from api then reloads the page
function deleteContact() {
fetch(`http://localhost:8000/delete-contact/${props.contactId}`, {
method: 'DELETE',
}).catch((err) => console.log(err));
setIsOpen(false);
window.location.reload(true);
}
// get contact from api by contact id
useEffect(() => {
async function fetchContact() {
await fetch(`http://localhost:8000/get-contact/${props.contactId}`)
.then((response) => response.json())
.then((data) => {
setContact(data);
})
.catch((err) => console.log(err));
}
if (props.open) {
fetchContact();
}
}, []);
function closeButtons() {
setIsOpen(false);
console.log(isOpen);
}
function openButtons() {
setIsOpen(true);
console.log(isOpen);
}
return (
<div className="bg-gray-100 p-4">
<div>
{/* <div className="mx-auto my-4 block w-fit rounded-full bg-gray-300 p-6 ">
...
</div> */}
<div className="flex flex-col text-center">
<span className="font-bold">
{contact.first_name} {contact.last_name}
</span>
<span className="text-sm text-gray-400">{contact.company}</span>
</div>
{contact.telephone !== '' || contact.telephone === 'NULL' ? (
<div className="my-4 flex flex-col rounded-md bg-white p-4 text-left">
<span className="text-sm font-medium">telephone</span>
<a
href={`tel:${contact.telephone}`}
className="text-sm text-blue-500"
>
{contact.telephone}
</a>
</div>
) : null}
{contact.email !== '' || contact.email === 'NULL' ? (
<div className="my-4 flex flex-col rounded-md bg-white p-4 text-left">
<span className="text-sm font-medium">email</span>
<a
href={`mailto:${contact.email}`}
className="text-sm text-blue-500"
>
{contact.email}
</a>
</div>
) : null}
{contact.address !== '' || contact.address === 'NULL' ? (
<div className="my-4 flex flex-col rounded-md bg-white p-4 text-left">
<span className="text-sm font-medium">address</span>
<span className="text-sm text-blue-500">{contact.address}</span>
</div>
) : null}
{contact.notes !== '' || contact.notes === 'NULL' ? (
<div className="my-4 flex flex-col rounded-md bg-white p-4 text-left">
<span className="text-sm font-medium">notes</span>
<span className="text-sm">{contact.notes}</span>
</div>
) : null}
</div>
{!isOpen ? <span>TRUE</span> : <span>FALSE</span>}
{!isOpen ? (
<div>
<div className="mt-6 flex flex-col">
<button className="mb-1 rounded bg-blue-500 px-4 py-3 capitalize text-white duration-100 ease-in-out hover:bg-blue-700">
<span className="text-center">edit</span>
</button>
<button
className="rounded bg-red-500 px-4 py-3 capitalize text-white duration-100 ease-in-out hover:bg-red-700"
onClick={closeButtons}
>
<span className="text-center tracking-wide">delete</span>
</button>
</div>
</div>
) : (
<div>
<div className="mt-6 flex flex-col">
<button className="mb-1 rounded bg-green-500 px-4 py-3 capitalize text-white duration-100 ease-in-out hover:bg-green-700">
<span className="text-center">edit</span>
</button>
<button
className="rounded bg-red-500 px-4 py-3 capitalize text-white duration-100 ease-in-out hover:bg-red-700"
onClick={deleteContact}
>
<span className="text-center tracking-wide">yes delete</span>
</button>
</div>
</div>
)}
</div>
);
}
Update with the whole component.
I am checking for isOpen to be false as I want to set some delete buttons, but then confirm the delete once the first set of buttons set isOpen to true

Categories

Resources