How to get side drawer to close when clicking on link - reactjs

I have a navbar component that opens a side drawer when clicking the burger menu on a mobile device. But when I click a link it goes to the 'page' but the side drawer does not close.
Do I have to add a click event to every link to change the toggle state to false? That seems like the wrong, long winded approach.
const NavBar = (props) => {
const [toggle, setToggled] = useState(false);
const toggleTrueFalse = () => setToggled(!toggle);
return (
<nav>
<div className="logo">
<h4>The nav</h4>
</div>
<ul className={toggle ? "nav-links nav-active" : "nav-links"}>
<li>
<Link to="/" activeclassname="active">
Home
</Link>
</li>
<li>
<Link to="/faq" activeclassname="active">
FAQ
</Link>
</li>
<li>
<Link to="/contact" activeclassname="active">
Contact us
</Link>
</li>
</ul>
<div
className={toggle ? "burger linetoggle" : "burger"}
onClick={toggleTrueFalse}
>
<div className="line1"></div>
<div className="line2"></div>
<div className="line3"></div>
</div>
</nav>
);
};
export default NavBar;

you can have link array and map it :
const links = []
\\in render
links.map((link,index)=>{
return(<li key=index onclick={toggleTrueFalse}>
<Link to={link.to} activeclassname="active">
{link.txt}
</Link>
</li>)
}

Related

make dropdown menu visible using react

I have following code with navbar and dropdown in it. All I want is to make the dropdown visible but I am not able to do it. What should I do. I have my code as
Header.jsx
import React, { useState } from 'react'
import { Link } from 'react-router-dom';
const Header = () => {
const [isVisible, setIsVisible] = useState(false);
return(
<div className="menu-container">
<nav className="nav">
<ul className="nav__menu">
<li className="nav__menu-item">
<Link to="Aboutus">About us</Link>
</li>
<li className="nav__menu-item">
<Link to="Myaccount">My account</Link>
</li>
<li className="nav__menu-item">
<Link to="Featured Product">Featured Product</Link>
</li>
<li className="nav__menu-item">
<Link to="WishList">WishList</Link>
</li>
<li className="nav__menu-items">
<Link to="Order Tracking">Order Tracking</Link>
</li>
<li className="nav__menu-items">
<Link to="English">English</Link>
{isVisible && (
<div>
<Link to className="box">English</Link>
<Link to className="box">German</Link>
<Link to className = "box">Spanish</Link>
</div>
)}
</li>
<li className="nav__menu-items">
<Link to="USD">USD</Link>
{isVisible && (
<div>
<Link to className="box">USD</Link>
<Link to className="box">INR</Link>
<Link to className="box">GBP</Link>
</div>
)}
</li>
</ul>
</nav>
</div>
)
}
export default Header
The code in the English and USD contains the dropdown but I am not able to make it possible visible. How can I make it visible.
Try this.
import React, { useState } from 'react'
import { Link } from 'react-router-dom';
const Header = () => {
const [isVisible, setIsVisible] = useState(false);
const toggle = () => {setIsVisible(!isVisible)}
return(
<div className="menu-container">
<nav className="nav">
<ul className="nav__menu">
<li className="nav__menu-item">
<Link to="Aboutus">About us</Link>
</li>
<li className="nav__menu-item">
<Link to="Myaccount">My account</Link>
</li>
<li className="nav__menu-item">
<Link to="Featured Product">Featured Product</Link>
</li>
<li className="nav__menu-item">
<Link to="WishList">WishList</Link>
</li>
<li className="nav__menu-items">
<Link to="Order Tracking">Order Tracking</Link>
</li>
<li className="nav__menu-items">
<Link to="English" onClick={toggle}>English</Link>
{isVisible && (
<div>
<Link to className="box">English</Link>
<Link to className="box">German</Link>
<Link to className = "box">Spanish</Link>
</div>
)}
</li>
<li className="nav__menu-items">
<Link to="USD" onClick={toggle}>USD</Link>
{isVisible && (
<div>
<Link to className="box">USD</Link>
<Link to className="box">INR</Link>
<Link to className="box">GBP</Link>
</div>
)}
</li>
</ul>
</nav>
</div>
)
}
export default Header
You don't change the value of isVisible in your code.
You should use setIsVisible function to set the new value of isVisible to true or false, as our want.

react-router-dom Link does not navigate to the start of target pages

I'm using react-router-dom Link on Home page to navigate to some routes. It works correctly when I'm at the top of Home Page. But when I scroll down the Home and click the Link items in navbar, although it navigates to the specified route, the target page is not displayed from the top. It starts somewhere in the middle of the page.
Here's my navbar:
import React, { Fragment, useState } from "react";
import { Link } from "react-router-dom";
import Fade from "react-reveal/Fade";
import EduLogo from "./resource/edu.png";
import Logo from "./resource/logo.png";
const Navbar = () => {
const [nav, setNav] = useState(false);
const adjustNav = () => {
if (window.scrollY >= 1) {
setNav(true);
document.getElementById("main-nav").style.height = "100px";
document.getElementById("nav-logo").style.height = "30px";
document.getElementById("nav-logo").style.width = "275px";
document.getElementById("nav-edu").style.height = "65px";
document.getElementById("nav-edu").style.width = "200px";
} else {
setNav(false);
document.getElementById("main-nav").style.height = "120px";
document.getElementById("nav-logo").style.height = "37px";
document.getElementById("nav-logo").style.width = "360px";
document.getElementById("nav-edu").style.height = "80px";
document.getElementById("nav-edu").style.width = "238px";
}
};
window.addEventListener("scroll", adjustNav);
return (
<Fragment>
<nav id="main-nav" className={nav ? "main-nav active" : "main-nav"}>
<Fade left>
<div id="main-nav-logo">
<a href="#!" target="_blank">
<img src={EduLogo} alt="" id="nav-edu" />
</a>
<img
src={Logo}
alt=""
id="nav-logo"
/>
</div>
</Fade>
<div className="nav-container">
<Fade bottom cascade>
<ul>
<li id="nav-item">
<Link to="/" className="nav-item">
Home
</Link>
</li>
<li id="nav-item">
<Link to="/members" className="nav-item">
Who We Are?
</Link>
</li>
<li id="nav-item">
<Link to="/research" className="nav-item">
What We Do?
</Link>
</li>
<li id="nav-item">
<Link to="/latest" className="nav-item">
News & Events
</Link>
</li>
</ul>
</Fade>
</div>
</nav>
</Fragment>
);
};
export default Navbar;
Any suggestion?
Thanks
I normally use something like this to make sure that my page is shown from the top whenever it is visited.
React.useLayoutEffect(() => {
window.scrollTo(0, 0);
}, [])
I use the useLayoutEffect hook to apply the window scroll before the browser starts painting.
You can read more about it here

How to close mobile menu in react when click on link?

I am making an app in react. I am facing issue as my mobile menu remains open even after clicking the navbar items. Does anyone know how it can be closed upon clicking on the navbar items?
class Navbar extends Component {
state = { clicked: false};
handleClick = () => {
this.setState({clicked:!this.state.clicked})
};
render () {
return (
<nav className={"NavbarItems"}>
<h1 className={"navbar-logo"}>React<i className={"fab fa-react"}></i></h1>
<div className={"menu-icon"} onClick={this.handleClick}>
<i className={this.state.clicked ? 'fas fa-times': 'fas fa-bars'}></i>
</div>
<ul className={this.state.clicked?'nav-menu active':'nav-menu'}>
{MenuItems.map((item, index) => {
return (
<div key={index}>
<li >
<Link className={item.cName} to={item.url}>
{item.title}
</Link>
</li>
</div>
)
})}
</ul>
<Button><Link className={"nav-button"} to="/contact">Contact Us</Link></Button>
</nav>
)
}
}
export default Navbar;
Could be like this:
<Link to={() => {
this.handleClick();
return '/contact'
}} >Contact Us</Link>

Materialize Hover button doesn't work with React Router

The problem: a Materialize CSS floating button works perfectly, but when I change page (with react router dom) for example HOME > ABOUT > HOME again it doesn't anymore.
Home:
import AddBtn from "../layout/AddBtn-float";
const Home = () => {
return (
<Fragment>
<SearchBar />
<div className="container">
<AddBtn />
...
AddBtn.js
const AddBtn = () => {
return (
<div className="fixed-action-btn direction-top">
<a
href="#add-task-modal"
className="btn-floating btn-large blue darken-2 modal-trigger"
>
<i className="large material-icons">add</i>
</a>
<ul>
<li>
<a
href="#user-list-modal"
className="btn-floating green modal-trigger"
>
<i className="material-icons">person</i>
</a>
</li>
<li>
<a href="#add-user-modal" className="btn-floating red modal-trigger">
<i className="material-icons">person_add</i>
</a>
</li>
</ul>
</div>
);
};
export default AddBtn;
I'm not an expert but looks like a Materialize "bug" that needs a workaround.
Any idea?
Thanks!
I write the solution may someone needs it.
Just put in every page
useEffect(() => {
M.AutoInit();
//eslint-disable-next-line
}, []);
I used it just in App.js but looks not enough

How to make Hamburger Icon menu function to work with single click in React.js?

I have been following a coding tutorial of making responsive Navbar from Youtube in Html,CSS and JS. While i really wanted to remake it again in react, the hamburger icon works flawlessly previously when i made it in plain Html, CSS and JS Click here to see the example. (Switch the browser in mobile view to see the Hamburger icon)
But when I copied all my code in react (as follows):
import React, { Component } from "react";
import "./style/navbar.css";
import { Link } from "react-router-dom";
class navbar extends Component {
render() {
const navslide = () => {
const burger = document.querySelector(".burger");
const nav = document.querySelector(".nav-links");
const navLinks = document.querySelectorAll(".nav-links li");
burger.addEventListener("click", () => {
nav.classList.toggle("nav-active");
navLinks.forEach((link, index) => {
if (link.style.animation) {
link.style.animation = "";
} else {
link.style.animation = `navLinkFade 0.5s ease forwards ${index / 7 +
0.5}s`;
}
});
burger.classList.toggle("toggle");
});
};
return (
<div>
<nav>
<div className="logo">
<h3>College Facemash</h3>
</div>
<ul className="nav-links">
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/login">Login / Signup</Link>
</li>
</ul>
<div className="burger" onClickCapture={navslide}>
<div className="line1"></div>
<div className="line2"></div>
<div className="line3"></div>
</div>
</nav>
</div>
);
}
}
export default navbar;
it worked well but not not functioning in single click. Instead it did required Double click to function.
Click here to see the demo.(Switch the browser in mobile view to see the Hamburger icon)
So, What changes should i made in order to make my code work flawlessly
Your help would be really valuable to me.
Thanks...
Try like this:
class Navbar extends Component {
const navslide = () => {
const nav = document.querySelector(".nav-links");
const navLinks = document.querySelectorAll(".nav-links li");
nav.classList.toggle("nav-active");
navLinks.forEach((link, index) => {
if (link.style.animation) {
link.style.animation = "";
} else {
link.style.animation = `navLinkFade 0.5s ease forwards ${index / 7 + 0.5}s`;
}
});
burger.classList.toggle("toggle");
});
};
render() {
return (
<div>
<nav>
<div className="logo">
<h3>College Facemash</h3>
</div>
<ul className="nav-links">
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/login">Login / Signup</Link>
</li>
</ul>
<div className="burger" onClick={() => navslide()}>
<div className="line1"></div>
<div className="line2"></div>
<div className="line3"></div>
</div>
</nav>
</div>
);
}
}
why calling burger.addEventListener("click") while your function will run on burger click! this is why it need 2 click to run!
import React, { Component } from "react";
import "./style/navbar.css";
import { Link } from "react-router-dom";
class navbar extends Component {
render() {
const navslide = () => {
const burger = document.querySelector(".burger");
const nav = document.querySelector(".nav-links");
const navLinks = document.querySelectorAll(".nav-links li");
nav.classList.toggle("nav-active");
navLinks.forEach((link, index) => {
if (link.style.animation) {
link.style.animation = "";
} else {
link.style.animation = `navLinkFade 0.5s ease forwards ${index / 7 +
0.5}s`;
}
});
burger.classList.toggle("toggle");
};
return (
<div>
<nav>
<div className="logo">
<h3>College Facemash</h3>
</div>
<ul className="nav-links">
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/login">Login / Signup</Link>
</li>
</ul>
<div className="burger" onClick={navslide}>
<div className="line1"></div>
<div className="line2"></div>
<div className="line3"></div>
</div>
</nav>
</div>
);
}
}
export default navbar;
also i recommend adding state to your component and changing it when ham is clicked!
and then you can change elements classes depending on this state.

Resources