I am working on a Vite+React Project, and currently I am working on mobile navbar so my first problem is when I first click on the mobile nav icon the nav component is showing but on the second click to hide the component its not working.
Second problem—->
On the first click it is showing its clickable but on the second click its not clickable although its a button.
My Navbar.jsx—->
import React, { useState } from 'react'
import { Link as ScrollLink } from 'react-scroll'
import { Link as RouterLink } from 'react-router-dom'
import companyLogo from '../assets/Images/SSlogo.png'
import navbar_menu_img from '../assets/Images/navbar-menuimg.png'
export default function Navbar({ isMobileMenuClicked, isnavMenuClicked }) {
return (
<nav className='fixed flex justify-around w-dvw h-20 border-b border-black bg-darkblue text-mintgreen items-center'>
<RouterLink >
<div className='mr-2 text-xl sm:text-2xl lg:text-3xl font-extrabold flex items-center'>
<div className='flex w-10 mr-5 ml-3 sm:w-14 lg:w-16 '>
<img src={companyLogo} alt='company_logo' className='rounded-full' />
</div>
<h1>SymptomSage</h1>
</div>
</RouterLink>
<ul className='Nav_lists hidden lg:flex justify-around w-4/12 text-lg '>
<li style={{ cursor: 'pointer' }}><ScrollLink to='home' smooth={true} duration={500} >Home</ScrollLink></li>
<li style={{ cursor: 'pointer' }}><ScrollLink to='services' smooth={true} duration={500} offset={-80}>Services</ScrollLink></li>
<li style={{ cursor: 'pointer' }}><ScrollLink to='contact' smooth={true} duration={500} offset={-90}>Contact</ScrollLink></li>
<li><RouterLink to='/register'>Register</RouterLink></li>
<li><RouterLink to='/login'>Login</RouterLink></li>
</ul>
<button className='w-8 md:w-10 lg:hidden ' onClick={() => isMobileMenuClicked(!isnavMenuClicked)} >
<img src={navbar_menu_img} alt='mobile_navbar_menu' />
</button>
</nav>
)
}
Home.jsx—->
import React from 'react'
import Navbar from '../components/Navbar'
import GetStartedbtn from '../components/GetStartedbtn'
import ServiceCard from '../components/ServiceCard'
import systemcheckimg from '../assets/Images/SymtomsCheckImg.jpg'
import healthsolimg from '../assets/Images/HealthsolutionImg.jpg'
import remediesimg from '../assets/Images/RemediesImg.jpg'
import healthtrackerimg from '../assets/Images/HealthtrackerImg.jpg'
import nutritionimg from '../assets/Images/NutritionImg.jpg'
import Button from '../components/Button'
import Footer from '../components/Footer'
import { useState } from 'react'
import MobileMenu from '../components/MobileMenu'
export default function Home() {
const [isnavMenuClicked, setMobileViewNav] = useState(false);
function isMobileMenuClicked(value) {
setMobileViewNav(value);
}
return (
<div id='home' className='flex bg-mintgreen w-full justify-center flex-col items-center'>
{/************************ hero section ********************************/}
<div className='flex bg-mintgreen w-full h-dvh justify-center '>
<Navbar isMobileMenuClicked={isMobileMenuClicked} isnavMenuClicked={isnavMenuClicked} />
{isnavMenuClicked &&
<div className='flex fixed w-full lg:hidden justify-end' >
<MobileMenu />
</div>}
<div className='flex text-darkblue text-bold justify-center items-center flex-col w-4/5 mt-5'>
<h1 className='text-5xl mb-5' >Understand Your Health with Confidence</h1>
<p className='mt-3 mb-5 text-center text-xl'>At SymptomSage, we empower you with instant insights into your well-being.
Describe your symptoms, and our AI-driven platform will provide personalized health suggestions
and actionable next steps to help you feel informed and in control.</p>
<p className='mt-20 mb-5 text-center text-2xl'>Your journey to better health starts here.</p>
<GetStartedbtn />
</div>
</div>
{/************************Services section ********************************/}
<div id='services' className='w-full bg-powderblue flex items-center pb-20 pt-20 flex-col'>
<h1 className='text-darkblue text-4xl font-extrabold'>Our Services</h1>
<ServiceCard img={systemcheckimg}
heading='Symptom Analysis'
subheading='Enter your symptoms, and our AI will analyze and suggest potential health issues.'
/>
<ServiceCard img={healthsolimg}
heading='Health Solutions'
subheading='Receive personalized suggestions for managing your symptoms at home or knowing when to seek medical help.'
/>
<ServiceCard img={remediesimg}
heading='Alternative Remedies and Precautions'
subheading='Discover natural remedies and simple precautions to support your health based on your symptoms.'
/>
<ServiceCard img={healthtrackerimg}
heading='Health Tracker'
subheading='Monitor and record your symptoms over time to gain insights into recurring health patterns.'
/>
<ServiceCard img={nutritionimg}
heading='Nutrition Advice'
subheading='Get tailored nutrition tips to help you eat better and manage your symptoms effectively.'
/>
<GetStartedbtn />
</div>
{/************************Contact section ********************************/}
<div id='contact' className='contact-form flex flex-col w-4/6 place-items-center items-center border-2 m-5 mt-14 pb-12 bg-gray-300 rounded-lg'>
<h1 className='mt-14 font-extrabold text-4xl mb-10'>Contact Us</h1>
<form className='flex flex-col w-4/6 '>
<label >Name</label>
<input type='text' placeholder="Enter Name" />
<label>Email id</label>
<input type='text' placeholder="Enter Mail" />
<label >Subject</label>
<input type='text' placeholder="Enter Subject" />
<label >Message</label>
<textarea rows="4" placeholder="Your message"></textarea>
<div className='flex justify-center mt-3'>
<Button />
</div>
</form>
</div>
{/************************Footer section ********************************/}
<Footer />
</div>
)
}
My mobileMenu.jsx—>
import React from 'react'
import { Link as ScrollLink } from 'react-scroll';
import { Link as RouterLink } from 'react-router-dom';
function MobileMenu() {
return (
<div className=' Nav_mobile w-2/4 text-sm flex-col mt-20 bg-darkblue' >
<ul className=' '>
<li style={{ cursor: 'pointer' }}><ScrollLink to='home' smooth={true} duration={500} >Home</ScrollLink></li>
<li style={{ cursor: 'pointer' }}><ScrollLink to='services' smooth={true} duration={500} offset={-80}>Services</ScrollLink></li>
<li style={{ cursor: 'pointer' }}><ScrollLink to='contact' smooth={true} duration={500} offset={-90}>Contact</ScrollLink></li>
<li><RouterLink to='/register'>Register</RouterLink></li>
<li><RouterLink to='/login'>Login</RouterLink></li>
</ul>
</div>
)
}
export default MobileMenu
I want that when I click on the menu icon my mobile menu should display and again it hide when I click on the menu icon.
2
Answers
This issue arrived because the navbar and mobile component both have z-index of 50, so they are blocking each other. So that my icon is not responding after mobile component display.
What you are doing seems a little bit convoluted, I have a few things to add.
Even tho react use state hook doesn’t require that the variable and setter names match, conventionally, it’s common to name them similarly tho ease the understanding process
Then, if this function does not have any other logic in it you don’t really need it:
if you remove it then you could pass the state setter to the navbar directly
and then in the navbar
This should now toggle on each click
Detailed:
First we need to define the useState hook (docs: https://react.dev/reference/react/useState) Basically what this does is create a new state variable that is initialised with the value passed to the hook and a setter for this variable. A state variable is a variable wich triggers a rerender, if needed, when its value is changed and also retains its current value.
Now the use:
Conventionally the name of the variable should reflect also in the set function, as you see in the example above. This is not functional but for easier reading.
In your case, you have
which personally i would change to
Why the changes. Firstly, the changed the setter to match the naem of the state variable. Secondly, i changed the variable name to match its functionality which is adding an element to the document if that variable has a certain value. So the state variable should reflect that, in this particular case, if the mobile menu is opened or not.
Now let’s get to the use case. Here, you are passing to the navbar a function:
the function:
This function has exacly the same functionality as the setter function returned by the useState hook so you could get rid of the extra function and pass the setter function directly.
Now we can take this a step further as the setter function can have only 2 values true/false and every time it is called it just negates the previous value, we can use this approach:
As you can see now, we pass a function to the navbar that calls the state variable setter and negates it
Now to the navbar where you use it:
here you need to change the onClick event to match the function passed in the isMobileMenuClicked attribute:
this should work as expected now.
There is one more thing i want to say, if you are new to programming, then of course it’s good to do those things so you learn how stuff works, if not, on the other hand, there are libraries that make your life easier, for example in your case, you could try material-ui (https://mui.com/material-ui/getting-started/) they have a lot of components to make your life easier, including an App Bar (https://mui.com/material-ui/react-app-bar/).