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.
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.
show
state that can be toggled true/false.onClick
handler to the Navbar.Toggle
component to handle opening the OffCanvas
component.show
and onHide
props to the Navbar.Offcanvas
to handle showing/hiding the OffCanvas
component.onClick
handler to each Link
component to toggle the show
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>
</>
);
};
Simpler implementation using a React ref.
Navbar.OffCanvas
component.onClick
handler to access the attached ref, the backdrop
element, and simulate a click event.onClick
handler to each Link
component to toggle the Navbar.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>
</>
);
};