我正在尝试制作一个单页应用,在其中单击链接,它向下滚动到与菜单项相对应的部分。我花了几天时间研究适合我的标准的修复程序,但不幸的是,我的运气很少。
我的标准如下:
我希望不要要求太多。
您可以玩我的CodeSandbox Here。感谢叉子!
您可以用forwardRef
HOC包装每个部分。为每个部分创建并设置一个ref
,然后将引用传递给标头组件,以便它可以在其上调用scrollIntoView
函数。如前所述,NavLink
不能使用onClick
道具,但是您可以将内部文本包装在span或div中,然后在其中附加onClick
处理程序。
edit添加了一个效果来查看位置并触发滚动。
const Header = ({ refs }) => {
const location = useLocation();
useEffect(() => {
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 => () => {
ref.current.scrollIntoView({ behavior: "smooth" });
};
return (
<>
<NavLink to="/hero" activeClassName="selected">
<div onClick={scrollSmoothHandler(refs.heroRef)}>
Hero
</div>
</NavLink>
<NavLink to="/about" activeClassName="selected">
<div onClick={scrollSmoothHandler(refs.aboutRef)}>
About
</div>
</NavLink>
<NavLink
to="/contact"
activeClassName="selected"
>
<div onClick={scrollSmoothHandler(refs.contactRef)}>
Contact
</div>
</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>
);
}