使用 useRef 响应滚动导航 [英] React scroll nav using useRef

查看:94
本文介绍了使用 useRef 响应滚动导航的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试制作一个单页应用程序,您可以在其中单击链接并向下滚动到与菜单项对应的部分.我花了几天时间研究适合我的标准的修复程序,但不幸的是,我运气不佳.

我的标准如下:

  • 无外部依赖
  • 地址栏中必须有网址(以允许直接链接到特定部分)
  • 不得乱码(即,将 URL 注入地址栏中)
  • 必须尽可能简单

我希望这不会要求太多.

你可以玩我的 CodeSandbox

I am trying to make a one page app where you click the link and it scrolls down to the section corresponding to the menu item. I have spent days researching for a fix that suits my criteria and unfortunately, I am having very little luck.

My criteria is as follows:

  • No external dependencies
  • Must have the url in the address bar (to allow direct links to the particular section)
  • Must not be hacky (i.e Injecting the URL into the address bar)
  • Must be as simple as possible

I hope that isn't asking for too much.

You can have a play around with my CodeSandbox Here. Forks are appreciated!

解决方案

You can wrap each section with the forwardRef HOC. Create and set a ref for each section, and pass the refs to the header component so it can call the scrollIntoView function on them.

edit Added an effect to look at the location and trigger scrolling.

const Header = ({ refs }) => {
  const location = useLocation();

  useEffect(() => {
    console.log("location", location.pathname);
    switch (location.pathname) {
      case "/about":
        scrollSmoothHandler(refs.aboutRef);
        break;
      case "/contact":
        scrollSmoothHandler(refs.contactRef);
        break;
      case "/hero":
        scrollSmoothHandler(refs.heroRef);
        break;

      default:
      // ignore
    }
  }, [location, refs]);

  const scrollSmoothHandler = ref => {
    console.log("Triggered.");
    ref.current.scrollIntoView({ behavior: "smooth" });
  };

  return (
    <>
      <NavLink to="/hero" activeClassName="selected">
        Hero
      </NavLink>
      <NavLink to="/about" activeClassName="selected">
        About
      </NavLink>
      <NavLink to="/contact" activeClassName="selected">
        Contact
      </NavLink>
    </>
  );
};

const Hero = forwardRef((props, ref) => {
  return (
    <section ref={ref}>
      <h1>Hero Section</h1>
    </section>
  );
});

const About = forwardRef((props, ref) => {
  return (
    <section ref={ref}>
      <h1>About Section</h1>
    </section>
  );
});

const Contact = forwardRef((props, ref) => {
  return (
    <section ref={ref}>
      <h1>Contact Section</h1>
    </section>
  );
});

function App() {
  const heroRef = useRef(null);
  const aboutRef = useRef(null);
  const contactRef = useRef(null);

  return (
    <div className="App">
      <HashRouter>
        <Header refs={{ aboutRef, contactRef, heroRef }} />
        <Hero ref={heroRef} />
        <About ref={aboutRef} />
        <Contact ref={contactRef} />
      </HashRouter>
    </div>
  );
}

这篇关于使用 useRef 响应滚动导航的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆