Reputation: 657
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:
I hope that isn't asking for too much.
You can have a play around with my CodeSandbox Here. Forks are appreciated!
Upvotes: 2
Views: 2231
Reputation: 203089
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>
);
}
Upvotes: 3