locomotive-scroll
locomotive-scroll copied to clipboard
How can I prevent layout issues when refreshing a page with a hash value in the URL while using the Link component from react-router for navigation and gsap?
I am using LocomotiveScroll in a React application and I have created a custom hook called useLocoScroll to handle the initialization and destruction of the LocomotiveScroll instance in order to make LocomotiveScroll work with gsap's ScrollTrigger. The hook works fine and I can use it to enable smooth scrolling and also use the ScrollTrigger in my app.
However, I now need to access the LocomotiveScroll instance from outside the hook so that I can call its methods directly. Specifically, I want to be able to call the scrollTo method on the nav buttons to scroll to a specific section.
The way I have it set up now is so I can use it like so const scroll = useLocoScroll(true)
in multiple files and destroy... I think only the last instance.
How can I modify this hook to allow me to access and use the LocomotiveScroll instance outside the hook without creating a new lomocotiveScroll instance every time?
Menu Component
const scroll = useLocoScroll(true); const handleLinkClick = (url) => { toggleNav && setToggleNav(false); scroll.scrollTo(url, { offset: 0, duration: 600, easing: [0.25, 0.0, 0.35, 1.0], disableLerp: true, }); };
App.jsx ` const scroll = useLocoScroll(true); const { pathname } = useLocation();
useEffect(() => { if (scroll) { scroll.scrollTo('top', { offset: 0, duration: 600, easing: [0.25, 0.0, 0.35, 1.0], disableLerp: true, }); } }, [pathname]);`
Custom Hook
`import { useRef, useLayoutEffect } from 'react'; import LocomotiveScroll from 'locomotive-scroll'; import gsap from 'gsap'; import ScrollTrigger from 'gsap/ScrollTrigger';
gsap.registerPlugin(ScrollTrigger);
let locoScroll;
const useLocoScroll = (start) => { const scrollRef = useRef(null);
useLayoutEffect(() => { if (!start) return;
const scrollEl = document.querySelector('.App');
if (!locoScroll) {
locoScroll = new LocomotiveScroll({
el: scrollEl,
smoothMobile: false,
smooth: true,
multiplier: 1,
});
locoScroll.on('scroll', ScrollTrigger.update);
ScrollTrigger.scrollerProxy(scrollEl, {
scrollTop(value) {
if (locoScroll) {
return arguments.length
? locoScroll.scrollTo(value, 0, 0)
: locoScroll.scroll.instance.scroll.y;
}
return null;
},
scrollLeft(value) {
if (locoScroll) {
return arguments.length
? locoScroll.scrollTo(value, 0, 0)
: locoScroll.scroll.instance.scroll.x;
}
return null;
},
getBoundingClientRect() {
return {
top: 0,
left: 0,
width: window.innerWidth,
height: window.innerHeight,
};
},
pinType: document.querySelector('.App').style.transform
? 'transform'
: 'fixed',
});
const locoScrollUpdate = () => {
if (locoScroll) {
locoScroll.update();
}
};
new ResizeObserver(() => {
if (locoScroll) {
locoScroll.update();
}
}).observe(document.querySelector('[data-scroll-container]'));
ScrollTrigger.addEventListener('refresh', locoScrollUpdate);
ScrollTrigger.refresh();
}
scrollRef.current = locoScroll;
return () => {
if (scrollRef.current === locoScroll) {
ScrollTrigger.removeEventListener('refresh', locoScroll.update);
locoScroll.destroy();
locoScroll = null;
}
};
}, [start]);
return scrollRef.current; };
export default useLocoScroll; `
Sorry for the weird code tags. I tried to fix it.
Currently, I am experiencing an issue where adding a hash value to the URL (such as #something) causes unexpected behavior when I refresh the page. This occurs because I am using the Link component from react-router for the navigation buttons. Although there are no errors displayed, the layout breaks in an unexpected way.
I am currently experiencing something similar as well.
I am currently using Locomotive scroll in my react app and my layout breaks whenever I refresh my page.