Any idea on how to hide/back to its original state when selecting the links inside offcanvas using react scroll?
Below is my code and also here is the sandbox code https://codesandbox.io/.
App.js
import React, { useState, useEffect } from "react"; import { BrowserRouter, Routes, Route } from "react-router-dom"; import HeaderContent from "./components/Header"; import Content from "./components/Content"; import "./styles.css"; export default function App() { return ( <BrowserRouter> <header> <HeaderContent /> </header> <main className="flex-shrink-0"> <React.Suspense fallback={<h6>Loading...</h6>}> <Routes> <Route path="/" element={<Content />} /> </Routes> </React.Suspense> </main> </BrowserRouter> ); }
Header.js
import React, { useState, useEffect } from "react"; import { Container, Offcanvas, Navbar, Nav, Image } from "react-bootstrap"; import { Link } from "react-scroll"; const Header = () => { const offsetValue = -56; return ( <> <Navbar bg="dark" variant="dark" expand={false} fixed="top"> <Container fluid> <Navbar.Brand href="#">Navbar Offcanvas</Navbar.Brand> <Navbar.Toggle aria-controls="offcanvasNavbar" /> <Navbar.Offcanvas id="offcanvasNavbar" aria-labelledby="offcanvasNavbarLabel" placement="end" > <Offcanvas.Header closeButton> <Offcanvas.Title id="offcanvasNavbarLabel"> Offcanvas </Offcanvas.Title> </Offcanvas.Header> <Offcanvas.Body> <Nav className="justify-content-end flex-grow-1 pe-3 offcanvas--menu"> <Link activeClass="active" to="home" spy={true} smooth={true} offset={offsetValue} duration={500} className="p-3 border-bottom border-dark text-decoration-none" > Home </Link> <Link activeClass="active" to="about" spy={true} smooth={true} offset={offsetValue} duration={500} className="p-3 border-bottom border-dark text-decoration-none" > About </Link> <Link activeClass="active" to="contact" spy={true} smooth={true} offset={offsetValue} duration={500} className="p-3 border-bottom border-dark text-decoration-none" > Contact </Link> </Nav> </Offcanvas.Body> </Navbar.Offcanvas> </Container> </Navbar> </> ); }; export default Header;
Content.js
const Content = () => ( <> <div className="pt-4"> <div id="home"> <h2>Home</h2> <p> Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. </p> <p> Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. </p> <p> Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. </p> <p> Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. </p> <p> Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. </p> </div> <div id="about"> <h2>About</h2> <p> Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. </p> <p> Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. </p> <p> Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. </p> <p> Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. </p> <p> Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. </p> </div> <div id="contact"> <h2>Contact</h2> <p> Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. </p> <p> Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. </p> <p> Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. </p> <p> Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. </p> <p> Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. </p> </div> </div> </> ); export default Content;
Im using the ff:
react 17.0.2
react-router-dom 6.2.2
react-scroll 1.8.7
react-bootstrap offcanvas 2.1.2 https://react-bootstrap.github.io/components/offcanvas/
I’m not sure if I missed something like useState/useEffect
or an attribute
to make it work.
Advertisement
Answer
I’m not a fan of bootstrap and I’m sure there’s a more vanilla Javascript/boostrap method for achieving this, but here’s a simple implementation using some local state.
- Add a
show
state that can be toggled true/false. - Add an
onClick
handler to theNavbar.Toggle
component to handle opening theOffCanvas
component. - Add the
show
andonHide
props to theNavbar.Offcanvas
to handle showing/hiding theOffCanvas
component. - Add an
onClick
handler to eachLink
component to toggle theshow
state.
Code
const Header = () => { const [show, setShow] = useState(false); const offsetValue = -56; const toggleOffCanvas = () => { setShow((show) => !show); }; return ( <> <Navbar ... > <Container fluid> <Navbar.Brand href="#">Navbar Offcanvas</Navbar.Brand> <Navbar.Toggle aria-controls="offcanvasNavbar" onClick={toggleOffCanvas} /> <Navbar.Offcanvas ... show={show} onHide={toggleOffCanvas} > <Offcanvas.Header closeButton> ... </Offcanvas.Header> <Offcanvas.Body> <Nav className="justify-content-end flex-grow-1 pe-3 offcanvas--menu"> <Link ... onClick={toggleOffCanvas} > Home </Link> <Link ... onClick={toggleOffCanvas} > About </Link> <Link ... onClick={toggleOffCanvas} > Contact </Link> </Nav> </Offcanvas.Body> </Navbar.Offcanvas> </Container> </Navbar> </> ); };
Update
Simpler implementation using a React ref.
- Create a ref for the
Navbar.OffCanvas
component. - Create an
onClick
handler to access the attached ref, thebackdrop
element, and simulate a click event. - Add an
onClick
handler to eachLink
component to toggle theNavbar.OffCanvas
component hidden.
Code
const Header = () => { const offCanvasRef = useRef(); const offsetValue = -56; const closeOffCanvas = () => offCanvasRef.current.backdrop.click(); return ( <> <Navbar bg="dark" variant="dark" expand={false} fixed="top"> <Container fluid> <Navbar.Brand href="#">Navbar Offcanvas</Navbar.Brand> <Navbar.Toggle aria-controls="offcanvasNavbar" /> <Navbar.Offcanvas ref={offCanvasRef} ... > <Offcanvas.Header closeButton> ... </Offcanvas.Header> <Offcanvas.Body> <Nav className="justify-content-end flex-grow-1 pe-3 offcanvas--menu"> <Link ... onClick={closeOffCanvas} > Home </Link> <Link ... className="p-3 border-bottom border-dark text-decoration-none" onClick={closeOffCanvas} > About </Link> <Link ... onClick={closeOffCanvas} > Contact </Link> </Nav> </Offcanvas.Body> </Navbar.Offcanvas> </Container> </Navbar> </> ); };