I just want to ask help with the comment section down below of the JavaScript Code. I want to work the toggle button / hamburger button but it does not work because addEventListener is not required for ReactJS. What code must be encoded? Thank you.
I am doing a Traversy Media Tutorial using Tailwind CSS. I want to use React as framework because of its composable component feature and efficiency to use.
import React from 'react';
import logo from '../images/logo.svg';
// const btn = document.getElementById('menu-btn')
// const nav = document.getElementById('menu')
// btn.addEventListener('click', () => {
// btn.classList.toggle('open')
// nav.classList.toggle('flex')
// nav.classList.toggle('hidden')
// })
const Navbar = () => {
return (
<div>
<nav className='relative container mx-auto p-6'>
{/* Flex Container */}
<div className='flex items-center justify-between'>
{/* Logo */}
<div className='pt-2'>
<img src={logo} alt='logo.svg'></img>
</div>
{/* Menu Items */}
<div className='hidden space-x-6 md:flex'>
<a href='/' className='hover:text-darkGrayishBlue'>
Pricing
</a>
<a href='/' className='hover:text-darkGrayishBlue'>
Product
</a>
<a href='/' className='hover:text-darkGrayishBlue'>
About Us
</a>
<a href='/' className='hover:text-darkGrayishBlue'>
Careers
</a>
<a href='/' className='hover:text-darkGrayishBlue'>
Community
</a>
</div>
{/* Button */}
<div>
<a
href='/'
className='hidden p-3 px-6 pt-2 text-white bg-brightRed rounded-full baseline hover:bg-brightRedLight md:block'
>
Get Started
</a>
</div>
{/* Hambuger Icon */}
<button
id='menu-btn'
className='block hamburger md:hidden focus:outline-none'
>
<span className='hamburger-top'></span>
<span className='hamburger-middle'></span>
<span className='hamburger-bottom'></span>
</button>
</div>
{/* Mobile Menu */}
<div className='md:hidden'>
<div
id='menu'
className='absolute flex-col items-center hidden self-end py-8 mt-10 space-y-6 font-bold bg-white sm:w-auto sm:self-center left-6 right-6 drop-shadow-md'
>
<a href='/'>Pricing</a>
<a href='/'>Product</a>
<a href='/'>About</a>
<a href='/'>Careers</a>
<a href='/'>Community</a>
</div>
</div>
</nav>
</div>
);
};
export default Navbar;
What you could do is define an open state and a click listener for the button.
Then change the class of the objects based on the open flag:
import React from 'react';
import logo from '../images/logo.svg';
const Navbar = () => {
const [open, setOpen] = useState(false);
const handleMenuClick = () => {
setOpen((prev) => !prev);
};
return (
<div>
<nav className='relative container mx-auto p-6'>
{/* Flex Container */}
<div className='flex items-center justify-between'>
{/* ... */}
{/* Hambuger Icon */}
<button
id='menu-btn'
className={`block hamburger md:hidden focus:outline-none ${
open && 'open'
}`}
onClick={() => handleMenuClick()}
>
<span className='hamburger-top'></span>
<span className='hamburger-middle'></span>
<span className='hamburger-bottom'></span>
</button>
</div>
{/* Mobile Menu */}
<div className='md:hidden'>
<div
id='menu'
className={`absolute flex-col items-center hidden self-end py-8 mt-10 space-y-6 font-bold bg-white sm:w-auto sm:self-center left-6 right-6 drop-shadow-md ${
open ? 'flex' : 'hidden'
}`}
>
<a href='/'>Pricing</a>
<a href='/'>Product</a>
<a href='/'>About</a>
<a href='/'>Careers</a>
<a href='/'>Community</a>
</div>
</div>
</nav>
</div>
);
};
export default Navbar;
```
You need to define the event handling where you define your button. In your case, it would look something like this:
<button
id='menu-btn'
className='block hamburger md:hidden focus:outline-none'
onClick={doAction}>
>
Official documentation regarding event handling in react.
Related
I just read all there is about JavaScript devtools sources panel and am still wondering is that the most current support for debugging declarative code. I am very comfortable with most debugging the imperative code (any language) but do not know what to do with a code like this (a section form the Redwood tutorial)
const BlogLayout = ({ children }) => {
const { logIn, logOut, isAuthenticated, currentUser } = useAuth()
return (
<>
<header className="relative flex justify-between items-center py-4 px-8 bg-blue-700 text-white">
<h1 className="text-5xl font-semibold tracking-tight">
<Link
className="text-blue-400 hover:text-blue-100 transition duration-100"
to={routes.home()}
>
Redwood Blog
</Link>
</h1>
<nav>
<ul className="relative flex items-center font-light">
<li>
<Link
className="py-2 px-4 hover:bg-blue-600 transition duration-100 rounded"
to={routes.about()}
>
About
</Link>
</li>
<li>
<Link
className="py-2 px-4 hover:bg-blue-600 transition duration-100 rounded"
to={routes.contact()}
>
Contact
</Link>
</li>
<li>
{isAuthenticated ? (
<div>
<button type="button" onClick={logOut} className="py-2 px-4">
Logout
</button>
</div>
) : (
<Link to={routes.login()} className="py-2 px-4">
Login
</Link>
)}
</li>
</ul>
{isAuthenticated && (
<div className="absolute bottom-1 right-0 mr-12 text-xs text-blue-300">
{currentUser.email}
</div>
)}
</nav>
</header>
<main className="max-w-4xl mx-auto p-12 bg-white shadow rounded-b">
{children}
</main>
</>
)
The Chrome debugger allows setting the breakpoints at selected places, but when I hit a breakpoint, I would like to view the function argument 'children' for example. The best I can get is
The code is for mobile menu but when I open it, it stays open and won't close.
I want it to close by clicking the menu links and tapping outside.
I know I haven't even added in the code but I don't know how to add into it.
Can anyone help me with the code? Any help is appreciated!
Here is the code :
import { useState } from "react";
import { HiMenuAlt3, HiX } from "react-icons/hi";
export default function NavBar() {
const [navbar, setNavbar] = useState(false);
return (
<nav className="w-full bg-white shadow">
<div className="justify-between px-4 mx-auto lg:max-w-7xl md:items-center md:flex md:px-8">
<div>
<div className="flex items-center justify-between py-3 md:py-5 md:block">
<a href="javascript:void(0)">
<h2 className="text-2xl font-bold">LOGO</h2>
</a>
<div className="md:hidden">
<button
className="p-2 text-gray-700 rounded-md outline-none focus:border-gray-400 focus:border"
onClick={() => setNavbar(!navbar)}
>
{navbar ? (
<HiX className="text-4xl" /> // Close icon
) : (
<HiMenuAlt3 className="text-4xl" /> // Open icon
)}
</button>
</div>
</div>
</div>
<div>
<div
className={`flex-1 justify-self-center pb-3 mt-8 md:block md:pb-0 md:mt-0 ${
navbar ? "block" : "hidden"
}`}
>
<ul className="items-center justify-center space-y-8 md:flex md:space-x-6 md:space-y-0">
<li className="text-gray-600 hover:text-blue-600">
Home
</li>
<li className="text-gray-600 hover:text-blue-600">
Blog
</li>
<li className="text-gray-600 hover:text-blue-600">
About US
</li>
<li className="text-gray-600 hover:text-blue-600">
Contact US
</li>
</ul>
</div>
</div>
</div>
</nav>
);
}
You do have code to close it, setNavbar(false). What you need is a hooked called useOnClickOutside. https://usehooks.com/useOnClickOutside/
To use it,
function NavBar() {
const ref = useRef()
useOnClickOutside(ref, () => setNavbar(false));
return (
<nav ref={ref}>
...
</nav>
)
}
I have been banging my head against the desk since last night trying to figure out what is causing this warning in my AstroJS project. I am currently building an AstroJS project with React components and without making any significant changes my terminal started through these errors when I run it in dev:
Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
You might have mismatching versions of React and the renderer (such as React DOM)
You might be breaking the Rules of Hooks
You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
I have been working with React for a while now and I am pretty sure I know how to use Hooks in functional components but maybe I am just blind and missing something. I have also checked for mismatching versions of React and renderer by running npm ls react and I can see that the versions are matching up:
#example/minimal#0.0.1 /Users/austinspinazze/Desktop/Projects/Uncharted-Labs-V1
└─┬ #astrojs/react#1.0.0
├─┬ react-dom#18.2.0
│ └── react#18.2.0 deduped
└── react#18.2.0
So that does not seem to be the problem either. I am also pretty certain I do not have more than one copy of React in my Astro project but I am not sure how to check for this?
Below are the only two React components in the Astro project so far:
Navbar
import React, { useState } from 'react';
const Navbar = () => {
const [mobileMenu, setMobileMenu] = useState(false);
const menuToggle = () => {
mobileMenu ? setMobileMenu(false) : setMobileMenu(true);
console.log(mobileMenu);
};
return (
<nav className={[' w-full mx-auto bg-green-white']}>
<div className='flex items-center justify-between space-x-20 px-10'>
<div className='z-30 '>
<img
src='/assets/Uncharted_Labs_1.png'
alt=''
id='logo'
className='max-h-24'
/>
</div>
<div className='hidden items-center md:space-x-10 uppercase text-dark-green md:flex'>
<a
href='#'
className='tracking-widest hover:border-b-2 hover:border-b-dark-green hover:mb-[-2px] ease-in-out duration-200'
>
About
</a>
<a
href='#'
className='tracking-widest hover:border-b-2 hover:border-b-dark-green hover:mb-[-2px] ease-in-out duration-200'
>
Services
</a>
<a
href='#'
className='tracking-widest hover:border-b-2 hover:border-b-dark-green hover:mb-[-2px] ease-in-out duration-200'
>
Pricing
</a>
<a
href='#'
className='tracking-widest hover:border-b-2 hover:border-b-dark-green hover:mb-[-2px] ease-in-out duration-200'
>
Blog
</a>
<a
href='#'
className='px-8 py-2 border-2 border-dark-green rounded-lg shadow-md hover:text-green-white hover:bg-dark-green ease-in-out duration-200 font-bold'
>
Contact
</a>
</div>
{/* Hamburger Button */}
<button
onClick={menuToggle}
className='space-y-2 md:hidden cursor-pointer'
>
<span className='block h-0.5 w-8 animate-pulse bg-gray-600'></span>
<span className='block h-0.5 w-8 animate-pulse bg-gray-600'></span>
<span className='block h-0.5 w-8 animate-pulse bg-gray-600'></span>
</button>
</div>
{/* Mobile menu */}
{mobileMenu && (
<div
id='menu'
className='absolute p-6 md:hidden rounded-b-lg bg-green-white left-6 right-6 top-30 z-100'
>
<div className='flex flex-col items-center justify-center w-full space-y-6 font-bold text-dark-green rounded-sm'>
<a href='#' className='w-full text-center'>
About
</a>
<a href='#' className='w-full text-center'>
Services
</a>
<a href='#' className='w-full text-center'>
Pricing
</a>
<a
href='#'
className='w-full pt-6 border-t border-gray-400 text-center'
>
Blog
</a>
<a
href='#'
className='w-full py-3 text-center rounded-full bg-dark-green text-green-white font-bold'
>
Contact
</a>
</div>
</div>
)}
</nav>
);
};
export default Navbar;
Hero
import React from 'react';
import styles from './styles.module.css';
const Hero = () => {
return (
<div className='flex flex-col gap-8 justify-items-center items-center mx-auto xl:px-20 px-10 lg:grid lg:grid-cols-hero'>
<div id='hero-text' className='max-w-xl'>
<h5 className='text-dark-green-text text-base leading-8 font-epilogue tracking-wide my-8'>
UNCHARTED LABS
</h5>
<h1 className='text-green-white font-epilogue font-bold my-8 xl:text-7xl text-5xl'>
The Simple, Clean Design
</h1>
<p className='text-light-grey-text font-epilogue leading-8 my-8 opacity-[.67]'>
Agency provides a full service range including technical
skills, design, and business understanding.
</p>
<button className='bg-dark-green-text pt-4 pb-3 px-5 rounded-md font-epilogue text-light-grey-text drop-shadow-md mt-5 font-bold'>
START EXPLORING
</button>
</div>
<div id='hero-img' className='max-w-xl lg:max-w-3xl'>
<div className={`${styles.blob}`}>
<image src='/assets/Hero.png' className='max-w-[120%]' />
</div>
</div>
</div>
);
};
export default Hero;
Astro file that is importing and using the Navbar and Hero components
---
import Hero from "../components/Hero/index";
import "../styles/global.css";
import Navbar from "../components/Navbar/index";
---
<html lang="en" class="top-0">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>Uncharted Labs</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Epilogue:wght#400;700&display=swap"
rel="stylesheet"
/>
</head>
<body class="bg-dark-green">
<Navbar client:load />
<main class="flex justify-center mt-20">
<section
class="flex mt-10 sm:items-center w-full h-screen sm:mt-0 lg:h-[80vh]"
>
<Hero />
</section>
</main>
</body>
</html>
So I found the issue but not the exact answer as to why this happening but apparently there is currently a bug in #astro/react that forces you to actually directly export a component like this:
export default function Navbar() {
const [mobileMenu, setMobileMenu] = useState(false);
const menuToggle = () => {
mobileMenu ? setMobileMenu(false) : setMobileMenu(true);
console.log(mobileMenu);
};
return (
<nav className={[' w-full mx-auto bg-green-white']}>
<div className='flex items-center justify-between space-x-20 px-10'>
<div className='z-30 '>
<img
src='/assets/Uncharted_Labs_1.png'
alt=''
id='logo'
className='max-h-24'
/>
</div>
<div className='hidden items-center md:space-x-10 uppercase text-dark-green md:flex'>
<a
href='#'
className='tracking-widest hover:border-b-2 hover:border-b-dark-green hover:mb-[-2px] ease-in-out duration-200'
>
About
</a>
<a
href='#'
className='tracking-widest hover:border-b-2 hover:border-b-dark-green hover:mb-[-2px] ease-in-out duration-200'
>
Services
</a>
<a
href='#'
className='tracking-widest hover:border-b-2 hover:border-b-dark-green hover:mb-[-2px] ease-in-out duration-200'
>
Pricing
</a>
<a
href='#'
className='tracking-widest hover:border-b-2 hover:border-b-dark-green hover:mb-[-2px] ease-in-out duration-200'
>
Blog
</a>
<a
href='#'
className='px-8 py-2 border-2 border-dark-green rounded-lg shadow-md hover:text-green-white hover:bg-dark-green ease-in-out duration-200 font-bold'
>
Contact
</a>
</div>
{/* Hamburger Button */}
<button
onClick={menuToggle}
className='space-y-2 md:hidden cursor-pointer'
>
<span className='block h-0.5 w-8 animate-pulse bg-gray-600'></span>
<span className='block h-0.5 w-8 animate-pulse bg-gray-600'></span>
<span className='block h-0.5 w-8 animate-pulse bg-gray-600'></span>
</button>
</div>
{/* Mobile menu */}
{mobileMenu && (
<div
id='menu'
className='absolute p-6 md:hidden rounded-b-lg bg-green-white left-6 right-6 top-30 z-100'
>
<div className='flex flex-col items-center justify-center w-full space-y-6 font-bold text-dark-green rounded-sm'>
<a href='#' className='w-full text-center'>
About
</a>
<a href='#' className='w-full text-center'>
Services
</a>
<a href='#' className='w-full text-center'>
Pricing
</a>
<a
href='#'
className='w-full pt-6 border-t border-gray-400 text-center'
>
Blog
</a>
<a
href='#'
className='w-full py-3 text-center rounded-full bg-dark-green text-green-white font-bold'
>
Contact
</a>
</div>
</div>
)}
</nav>
);
}
If you would like to read more about potentially why this happening and maybe want a fun PR to resolve you can check out this Github issue https://github.com/withastro/astro/issues/4220
When I click on the menu icon in the navbar, which allows me to set a state, the page completely freezes and crashes.
If I use useState(true) the menu becomes visible without any problem.
So does useState(false).
I tried useCallback and useEffect. When I tried useEffect, the menu opened when I refreshed the page, but in this way, I could not manage the menu with a button. When I tried useCallback I got the same error with useState.
Please help I lost my youth
Code:
import React, {useState} from 'react';
import {Menu} from '#mui/icons-material';
function Navbar() {
const [menuClicked, setMenuClicked] = useState(false);
const updateMenu = () => {
setMenuClicked(!menuClicked)
}
return(
<div className='h-16 z-20 relative'>
<div className='fixed top-0 text-left text-6xl font-bold items-center bg-white/40 h-20 w-full flex dark:text-white dark:bg-neutral-900/40'>
<div className='flex flex-1 items-center pb-5'>
<span className='pl-4'>psue</span>
</div>
<div className='flex justify-end w-7/12 scale-0 md:scale-100 items-center'>
<ul className='flex text-xl gap-12 pb-0'>
<li className=''>
<a href='/'>Home</a>
</li>
<li>
<a href='/livechat'>Live Chat</a>
</li>
<li>
{checkLogin ? (<a href='/profile'>{auth.currentUser.email.substring(0, auth.currentUser.email.indexOf('#'))}</a>) : (<a onClick={signOutFunction} href='/login'>Login</a>)}
</li>
</ul>
</div>
<div className='z-20 pr-5 pb-5 scale-150 overflow-x-hidden md:scale-0'>
<Menu onClick={() => updateMenu()} className='cursor-pointer'/>
</div>
</div>
<div className={menuClicked ? 'translate-x-0 transition fixed bottom-0 top-0 right-0 h-screen w-64 z-10' : 'transition translate-x-72 fixed top-0 right-0 h-screen w-0'}>
<div className='bg-white/30 dark:bg-neutral-900/30 dark:text-white fixed right-0 top-0 w-full h-full'>
<ul className='flex flex-col text-xl gap-16 h-full w-full justify-center items-center backdrop-blur-lg font-bold'>
<li>
<CloseIcon onClick={() => updateMenu()} className='cursor-pointer scale-150 fixed top-24'/>
</li>
<li className=''>
<a href='/'>Home</a>
</li>
<li>
<a href='/livechat'>Live Chat</a>
</li>
<li>
{checkLogin ? (<a href='/profile'>{auth.currentUser.email.substring(0, auth.currentUser.email.indexOf('#'))}</a>) : (<a onClick={signOutFunction} href='/login'>Login</a>)}
</li>
</ul>
</div>
</div>
</div>
)
}
export default Navbar;
I have a list of projects, on one side I list their names, and on the other their image.
The images are in absolute position.
I want to change the Z-index of an image when I hover over the project name, how do I achieve it?
Here is the main Work Page:
<main className='w-full h-full text-gray-50 text-lg py-32'>
<div className='container flex content-center w-full h-full '>
<header className='px-12 flex flex-col justify-center'>
<h1 className='bg-clip-text text-transparent bg-gradient-to-r from-red-600 to-yellow-600 text-8xl font-bold'>
Recent Work
</h1>
<ul className='mt-12 flex flex-col gap-4'>
{projectsData.map((project) => (
<WorkInfo key={project.id} project={project} />
))}
</ul>
</header>
<section className='px-12 flex-grow'>
<div className='max-w-xs w-full h-full'>
<ul className='relative w-full h-full'>
{projectsData.map((project, index) => (
<WorkImage
key={project.id}
project={project}
index={index}
isHover={isHover}
/>
))}
</ul>
</div>
</section>
</div>
</main>
Here is the WorkImage component, where I list the Images of the projects:
const WorkImage = ({ index, isHover, project }) => {
return (
<li className={`absolute w-full h-full`}>
<Image
src={project.image}
alt={project.title}
layout='fill'
blurDataURL
placeholder='blur'
className='w-full h-full object-cover'
/>
</li>
);
};
Here is the WorkInfo component, where I list the names of projects:
const WorkInfo = ({ project }) => {
return (
<li key={project.id} className='max-w-xs group'>
<a
href={project.url}
target='_blank'
rel='noopener noreferrer'
className='flex gap-1 items-center'>
<div className='h-px w-0 group-hover:w-full bg-gray-50 transition-all duration-700'></div>
<h3 className='whitespace-pre'>{project.title}</h3>
</a>
</li>
);
};