locomotive-scroll icon indicating copy to clipboard operation
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?

Open CodyHiII opened this issue 1 year ago • 1 comments

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.

CodyHiII avatar May 09 '23 19:05 CodyHiII

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.

Abayomzee avatar Jun 11 '23 01:06 Abayomzee