yarn add @n8tb1t/use-scroll-position
Navbarがヘッダー部分に相当するコンポーネント
クラス型になっているので関数型に書き直し
useScrollPositionを使えるようにする
元のコード
import React from "react";
import { Link } from "gatsby";
import github from "../img/github-icon.svg";
import logo from "../img/logo.svg";
const Navbar = class extends React.Component {
constructor(props) {
super(props);
this.state = {
active: false,
navBarActiveClass: "",
};
}
toggleHamburger() {
// toggle the active boolean in the state
this.setState(
{
active: !this.state.active,
},
// after state has been updated,
() => {
// set the class in state for the navbar accordingly
this.state.active
? this.setState({
navBarActiveClass: "is-active",
})
: this.setState({
navBarActiveClass: "",
});
}
);
}
render() {
return (
<nav
className="navbar is-transparent"
role="navigation"
aria-label="main-navigation"
>
<div className="container">
<div className="navbar-brand">
<Link to="/" className="navbar-item" title="Logo">
<img src={logo} alt="hi1t0" style={{ width: "88px" }} />
</Link>
<Link className="navbar-item" to="/cart">
Cart
</Link>
{/* Hamburger menu */}
<div
className={`navbar-burger burger ${this.state.navBarActiveClass}`}
data-target="navMenu"
role="menuitem"
tabIndex={0}
onKeyPress={() => this.toggleHamburger()}
onClick={() => this.toggleHamburger()}
>
<span />
<span />
<span />
</div>
</div>
<div
id="navMenu"
className={`navbar-menu ${this.state.navBarActiveClass}`}
>
<div className="navbar-start has-text-centered">
<Link className="navbar-item" to="/products">
Products
</Link>
<Link className="navbar-item" to="/blog">
Blog
</Link>
<Link className="navbar-item" to="/about">
About
</Link>
<Link className="navbar-item" to="/contact">
Contact
</Link>
</div>
<div className="navbar-end has-text-centered">
<a
className="navbar-item"
href="https://github.com/hi1t0/"
target="_blank"
rel="noopener noreferrer"
>
<span className="icon">
<img src={github} alt="Github" />
</span>
</a>
</div>
</div>
</div>
</nav>
);
}
};
export default Navbar;
htmlのnavタグのスタイルをshowMenu
の内容によって書き換えている
完成形
import React, { useState } from "react";
import { Link } from "gatsby";
import github from "../img/github-icon.svg";
import logo from "../img/logo.svg";
import { useScrollPosition } from '@n8tb1t/use-scroll-position';
const headerStyleVisible = {
visible: "visible",
transition: "all 200ms ease-in",
transform: "none",
position: "fixed",
width: "100%",
}
const headerStyleHidden = {
visible: "hidden",
transition: "all 200ms ease-out",
transform: "translate(0, -100%)",
position: "fixed",
width: "100%",
}
const Navbar = () => {
const [active, setActive] = useState(false)
const [navBarActiveClass, setNavBarActiveClass] = useState("")
const [showMenu, setShowMenu] = useState(true);
useScrollPosition(({ prevPos, currPos }) => {
const visible = currPos.y > prevPos.y;
setShowMenu(visible);
}, []);
const toggleHamburger = () => {
// toggle the active boolean in the state
setActive(!active)
// set the class in state for the navbar accordingly
if (active) setNavBarActiveClass("is-active")
else setNavBarActiveClass("")
}
return (
<nav
style={showMenu ? headerStyleVisible : headerStyleHidden}
className="navbar is-transparent"
role="navigation"
aria-label="main-navigation"
>
<div className="container">
<div className="navbar-brand">
<Link to="/" className="navbar-item" title="Logo">
<img src={logo} alt="hi1t0" style={{ width: "88px" }} />
</Link>
<Link className="navbar-item" to="/cart">
Cart
</Link>
{/* Hamburger menu */}
<div
className={`navbar-burger burger ${navBarActiveClass}`}
data-target="navMenu"
role="menuitem"
tabIndex={0}
onKeyPress={() => toggleHamburger()}
onClick={() => toggleHamburger()}
>
<span />
<span />
<span />
</div>
</div>
<div
id="navMenu"
className={`navbar-menu ${navBarActiveClass}`}
>
<div className="navbar-start has-text-centered">
<Link className="navbar-item" to="/products">
Products
</Link>
<Link className="navbar-item" to="/blog">
Blog
</Link>
<Link className="navbar-item" to="/about">
About
</Link>
<Link className="navbar-item" to="/contact">
Contact
</Link>
</div>
<div className="navbar-end has-text-centered">
<a
className="navbar-item"
href="https://github.com/hi1t0/"
target="_blank"
rel="noopener noreferrer"
>
<span className="icon">
<img src={github} alt="Github" />
</span>
</a>
</div>
</div>
</div>
</nav>
)
}
export default Navbar
参考