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
JavaScript
x
25
25
1
import React, { useState, useEffect } from "react";
2
import { BrowserRouter, Routes, Route } from "react-router-dom";
3
import HeaderContent from "./components/Header";
4
import Content from "./components/Content";
5
6
import "./styles.css";
7
8
export default function App() {
9
return (
10
<BrowserRouter>
11
<header>
12
<HeaderContent />
13
</header>
14
15
<main className="flex-shrink-0">
16
<React.Suspense fallback={<h6>Loading</h6>}>
17
<Routes>
18
<Route path="/" element={<Content />} />
19
</Routes>
20
</React.Suspense>
21
</main>
22
</BrowserRouter>
23
);
24
}
25
Header.js
JavaScript
1
69
69
1
import React, { useState, useEffect } from "react";
2
import { Container, Offcanvas, Navbar, Nav, Image } from "react-bootstrap";
3
import { Link } from "react-scroll";
4
5
const Header = () => {
6
const offsetValue = -56;
7
8
return (
9
<>
10
<Navbar bg="dark" variant="dark" expand={false} fixed="top">
11
<Container fluid>
12
<Navbar.Brand href="#">Navbar Offcanvas</Navbar.Brand>
13
<Navbar.Toggle aria-controls="offcanvasNavbar" />
14
<Navbar.Offcanvas
15
id="offcanvasNavbar"
16
aria-labelledby="offcanvasNavbarLabel"
17
placement="end"
18
>
19
<Offcanvas.Header closeButton>
20
<Offcanvas.Title id="offcanvasNavbarLabel">
21
Offcanvas
22
</Offcanvas.Title>
23
</Offcanvas.Header>
24
<Offcanvas.Body>
25
<Nav className="justify-content-end flex-grow-1 pe-3 offcanvas--menu">
26
<Link
27
activeClass="active"
28
to="home"
29
spy={true}
30
smooth={true}
31
offset={offsetValue}
32
duration={500}
33
className="p-3 border-bottom border-dark text-decoration-none"
34
>
35
Home
36
</Link>
37
<Link
38
activeClass="active"
39
to="about"
40
spy={true}
41
smooth={true}
42
offset={offsetValue}
43
duration={500}
44
className="p-3 border-bottom border-dark text-decoration-none"
45
>
46
About
47
</Link>
48
<Link
49
activeClass="active"
50
to="contact"
51
spy={true}
52
smooth={true}
53
offset={offsetValue}
54
duration={500}
55
className="p-3 border-bottom border-dark text-decoration-none"
56
>
57
Contact
58
</Link>
59
</Nav>
60
</Offcanvas.Body>
61
</Navbar.Offcanvas>
62
</Container>
63
</Navbar>
64
</>
65
);
66
};
67
68
export default Header;
69
Content.js
JavaScript
1
183
183
1
const Content = () => (
2
<>
3
<div className="pt-4">
4
<div id="home">
5
<h2>Home</h2>
6
<p>
7
Lorem Ipsum is simply dummy text of the printing and typesetting
8
industry. Lorem Ipsum has been the industry's standard dummy text ever
9
since the 1500s, when an unknown printer took a galley of type and
10
scrambled it to make a type specimen book. It has survived not only
11
five centuries, but also the leap into electronic typesetting,
12
remaining essentially unchanged. It was popularised in the 1960s with
13
the release of Letraset sheets containing Lorem Ipsum passages, and
14
more recently with desktop publishing software like Aldus PageMaker
15
including versions of Lorem Ipsum.
16
</p>
17
<p>
18
Lorem Ipsum is simply dummy text of the printing and typesetting
19
industry. Lorem Ipsum has been the industry's standard dummy text ever
20
since the 1500s, when an unknown printer took a galley of type and
21
scrambled it to make a type specimen book. It has survived not only
22
five centuries, but also the leap into electronic typesetting,
23
remaining essentially unchanged. It was popularised in the 1960s with
24
the release of Letraset sheets containing Lorem Ipsum passages, and
25
more recently with desktop publishing software like Aldus PageMaker
26
including versions of Lorem Ipsum.
27
</p>
28
<p>
29
Lorem Ipsum is simply dummy text of the printing and typesetting
30
industry. Lorem Ipsum has been the industry's standard dummy text ever
31
since the 1500s, when an unknown printer took a galley of type and
32
scrambled it to make a type specimen book. It has survived not only
33
five centuries, but also the leap into electronic typesetting,
34
remaining essentially unchanged. It was popularised in the 1960s with
35
the release of Letraset sheets containing Lorem Ipsum passages, and
36
more recently with desktop publishing software like Aldus PageMaker
37
including versions of Lorem Ipsum.
38
</p>
39
<p>
40
Lorem Ipsum is simply dummy text of the printing and typesetting
41
industry. Lorem Ipsum has been the industry's standard dummy text ever
42
since the 1500s, when an unknown printer took a galley of type and
43
scrambled it to make a type specimen book. It has survived not only
44
five centuries, but also the leap into electronic typesetting,
45
remaining essentially unchanged. It was popularised in the 1960s with
46
the release of Letraset sheets containing Lorem Ipsum passages, and
47
more recently with desktop publishing software like Aldus PageMaker
48
including versions of Lorem Ipsum.
49
</p>
50
<p>
51
Lorem Ipsum is simply dummy text of the printing and typesetting
52
industry. Lorem Ipsum has been the industry's standard dummy text ever
53
since the 1500s, when an unknown printer took a galley of type and
54
scrambled it to make a type specimen book. It has survived not only
55
five centuries, but also the leap into electronic typesetting,
56
remaining essentially unchanged. It was popularised in the 1960s with
57
the release of Letraset sheets containing Lorem Ipsum passages, and
58
more recently with desktop publishing software like Aldus PageMaker
59
including versions of Lorem Ipsum.
60
</p>
61
</div>
62
<div id="about">
63
<h2>About</h2>
64
<p>
65
Lorem Ipsum is simply dummy text of the printing and typesetting
66
industry. Lorem Ipsum has been the industry's standard dummy text ever
67
since the 1500s, when an unknown printer took a galley of type and
68
scrambled it to make a type specimen book. It has survived not only
69
five centuries, but also the leap into electronic typesetting,
70
remaining essentially unchanged. It was popularised in the 1960s with
71
the release of Letraset sheets containing Lorem Ipsum passages, and
72
more recently with desktop publishing software like Aldus PageMaker
73
including versions of Lorem Ipsum.
74
</p>
75
<p>
76
Lorem Ipsum is simply dummy text of the printing and typesetting
77
industry. Lorem Ipsum has been the industry's standard dummy text ever
78
since the 1500s, when an unknown printer took a galley of type and
79
scrambled it to make a type specimen book. It has survived not only
80
five centuries, but also the leap into electronic typesetting,
81
remaining essentially unchanged. It was popularised in the 1960s with
82
the release of Letraset sheets containing Lorem Ipsum passages, and
83
more recently with desktop publishing software like Aldus PageMaker
84
including versions of Lorem Ipsum.
85
</p>
86
<p>
87
Lorem Ipsum is simply dummy text of the printing and typesetting
88
industry. Lorem Ipsum has been the industry's standard dummy text ever
89
since the 1500s, when an unknown printer took a galley of type and
90
scrambled it to make a type specimen book. It has survived not only
91
five centuries, but also the leap into electronic typesetting,
92
remaining essentially unchanged. It was popularised in the 1960s with
93
the release of Letraset sheets containing Lorem Ipsum passages, and
94
more recently with desktop publishing software like Aldus PageMaker
95
including versions of Lorem Ipsum.
96
</p>
97
<p>
98
Lorem Ipsum is simply dummy text of the printing and typesetting
99
industry. Lorem Ipsum has been the industry's standard dummy text ever
100
since the 1500s, when an unknown printer took a galley of type and
101
scrambled it to make a type specimen book. It has survived not only
102
five centuries, but also the leap into electronic typesetting,
103
remaining essentially unchanged. It was popularised in the 1960s with
104
the release of Letraset sheets containing Lorem Ipsum passages, and
105
more recently with desktop publishing software like Aldus PageMaker
106
including versions of Lorem Ipsum.
107
</p>
108
<p>
109
Lorem Ipsum is simply dummy text of the printing and typesetting
110
industry. Lorem Ipsum has been the industry's standard dummy text ever
111
since the 1500s, when an unknown printer took a galley of type and
112
scrambled it to make a type specimen book. It has survived not only
113
five centuries, but also the leap into electronic typesetting,
114
remaining essentially unchanged. It was popularised in the 1960s with
115
the release of Letraset sheets containing Lorem Ipsum passages, and
116
more recently with desktop publishing software like Aldus PageMaker
117
including versions of Lorem Ipsum.
118
</p>
119
</div>
120
<div id="contact">
121
<h2>Contact</h2>
122
<p>
123
Lorem Ipsum is simply dummy text of the printing and typesetting
124
industry. Lorem Ipsum has been the industry's standard dummy text ever
125
since the 1500s, when an unknown printer took a galley of type and
126
scrambled it to make a type specimen book. It has survived not only
127
five centuries, but also the leap into electronic typesetting,
128
remaining essentially unchanged. It was popularised in the 1960s with
129
the release of Letraset sheets containing Lorem Ipsum passages, and
130
more recently with desktop publishing software like Aldus PageMaker
131
including versions of Lorem Ipsum.
132
</p>
133
<p>
134
Lorem Ipsum is simply dummy text of the printing and typesetting
135
industry. Lorem Ipsum has been the industry's standard dummy text ever
136
since the 1500s, when an unknown printer took a galley of type and
137
scrambled it to make a type specimen book. It has survived not only
138
five centuries, but also the leap into electronic typesetting,
139
remaining essentially unchanged. It was popularised in the 1960s with
140
the release of Letraset sheets containing Lorem Ipsum passages, and
141
more recently with desktop publishing software like Aldus PageMaker
142
including versions of Lorem Ipsum.
143
</p>
144
<p>
145
Lorem Ipsum is simply dummy text of the printing and typesetting
146
industry. Lorem Ipsum has been the industry's standard dummy text ever
147
since the 1500s, when an unknown printer took a galley of type and
148
scrambled it to make a type specimen book. It has survived not only
149
five centuries, but also the leap into electronic typesetting,
150
remaining essentially unchanged. It was popularised in the 1960s with
151
the release of Letraset sheets containing Lorem Ipsum passages, and
152
more recently with desktop publishing software like Aldus PageMaker
153
including versions of Lorem Ipsum.
154
</p>
155
<p>
156
Lorem Ipsum is simply dummy text of the printing and typesetting
157
industry. Lorem Ipsum has been the industry's standard dummy text ever
158
since the 1500s, when an unknown printer took a galley of type and
159
scrambled it to make a type specimen book. It has survived not only
160
five centuries, but also the leap into electronic typesetting,
161
remaining essentially unchanged. It was popularised in the 1960s with
162
the release of Letraset sheets containing Lorem Ipsum passages, and
163
more recently with desktop publishing software like Aldus PageMaker
164
including versions of Lorem Ipsum.
165
</p>
166
<p>
167
Lorem Ipsum is simply dummy text of the printing and typesetting
168
industry. Lorem Ipsum has been the industry's standard dummy text ever
169
since the 1500s, when an unknown printer took a galley of type and
170
scrambled it to make a type specimen book. It has survived not only
171
five centuries, but also the leap into electronic typesetting,
172
remaining essentially unchanged. It was popularised in the 1960s with
173
the release of Letraset sheets containing Lorem Ipsum passages, and
174
more recently with desktop publishing software like Aldus PageMaker
175
including versions of Lorem Ipsum.
176
</p>
177
</div>
178
</div>
179
</>
180
);
181
182
export default Content;
183
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
JavaScript
1
55
55
1
const Header = () => {
2
const [show, setShow] = useState(false);
3
4
const offsetValue = -56;
5
6
const toggleOffCanvas = () => {
7
setShow((show) => !show);
8
};
9
10
return (
11
<>
12
<Navbar >
13
<Container fluid>
14
<Navbar.Brand href="#">Navbar Offcanvas</Navbar.Brand>
15
<Navbar.Toggle
16
aria-controls="offcanvasNavbar"
17
onClick={toggleOffCanvas}
18
/>
19
<Navbar.Offcanvas
20
21
show={show}
22
onHide={toggleOffCanvas}
23
>
24
<Offcanvas.Header closeButton>
25
26
</Offcanvas.Header>
27
<Offcanvas.Body>
28
<Nav className="justify-content-end flex-grow-1 pe-3 offcanvas--menu">
29
<Link
30
31
onClick={toggleOffCanvas}
32
>
33
Home
34
</Link>
35
<Link
36
37
onClick={toggleOffCanvas}
38
>
39
About
40
</Link>
41
<Link
42
43
onClick={toggleOffCanvas}
44
>
45
Contact
46
</Link>
47
</Nav>
48
</Offcanvas.Body>
49
</Navbar.Offcanvas>
50
</Container>
51
</Navbar>
52
</>
53
);
54
};
55
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
JavaScript
1
49
49
1
const Header = () => {
2
const offCanvasRef = useRef();
3
const offsetValue = -56;
4
5
const closeOffCanvas = () => offCanvasRef.current.backdrop.click();
6
7
return (
8
<>
9
<Navbar bg="dark" variant="dark" expand={false} fixed="top">
10
<Container fluid>
11
<Navbar.Brand href="#">Navbar Offcanvas</Navbar.Brand>
12
<Navbar.Toggle aria-controls="offcanvasNavbar" />
13
<Navbar.Offcanvas
14
ref={offCanvasRef}
15
16
>
17
<Offcanvas.Header closeButton>
18
19
</Offcanvas.Header>
20
<Offcanvas.Body>
21
<Nav className="justify-content-end flex-grow-1 pe-3 offcanvas--menu">
22
<Link
23
24
onClick={closeOffCanvas}
25
>
26
Home
27
</Link>
28
<Link
29
30
className="p-3 border-bottom border-dark text-decoration-none"
31
onClick={closeOffCanvas}
32
>
33
About
34
</Link>
35
<Link
36
37
onClick={closeOffCanvas}
38
>
39
Contact
40
</Link>
41
</Nav>
42
</Offcanvas.Body>
43
</Navbar.Offcanvas>
44
</Container>
45
</Navbar>
46
</>
47
);
48
};
49