tl;dr Don't miss the solution at the end!
Looking to create a slide up and down effect on a fixed navbar in react?
What's the best approach - using refs or the componentDidMount lifecycle hook?
hideNav = (navbar) => {
const hide = () => {
let lastScrollTop = 0;
const currentScrollTop = navbar.scrollTop;
// scrolling down
if (currentScrollTop > lastScrollTop) {
navbar.classList.add('hidden');
} else {
// scrolling up
navbar.classList.remove('hidden');
}
lastScrollTop = currentScrollTop;
};
window.addEventListener('scroll', hide);
};
... scroll further down in the render method:
render() {
return <Navbar ref={this.hideNav} />
UPDATE:
Here is the solution:
class Navbar extends React.Component {
state = {
auth: false,
slide: 0, // Set how much the Navbar should slide up or down
lastScrollY: 0, // Keep track of current position in state
};
componentWillMount() {
// Start listening for scroll changes when this component mounts
window.addEventListener('scroll', this.handleScroll);
}
componentWillUnmount() {
// Stop listening for scroll changes when this component is unmounted
window.removeEventListener('scroll', this.handleScroll);
}
handleScroll = () => {
const { lastScrollY } = this.state;
const currentScrollY = window.scrollY;
if (currentScrollY > lastScrollY) {
this.setState({ slide: '-48px' });
} else {
this.setState({ slide: '0px' });
}
this.setState({ lastScrollY: currentScrollY });
};
render() {
return (
<Navbar
style={{
transform: `translate(0, ${this.state.slide})`,
transition: 'transform 90ms linear',
}}
/>
);
}
}
No optimizations are done yet, so it's suggested to throttle the event using requestAnimationFrame, setTimeout, or customEvent. Check here for an example.