React Hooks Scroll To Element
Solution 1:
If you don't mind using react-router-dom
, then you can track history changes and update the scroll position to an HTML element's id
via a hash
history change. The advantage of this approach is you don't have to utilize state, nor utilize refs, and it can scale across the entire application (regardless of where the elements are located within the application's tree, you can scroll to them).
Working example:
https://fglet.codesandbox.io/ (demo)
https://codesandbox.io/s/fglet (source -- unfortunately, doesn't work within the codesandbox editor)
components/ScrollHandler (hook that listens to hash history changes, searches for elements that match the id located within the hash and, if it finds a matching element id, then it'll scroll to the element)
import { useEffect } from"react";
importPropTypesfrom"prop-types";
import { withRouter } from"react-router-dom";
constScrollHandler = ({ location }) => {
useEffect(() => {
const element = document.getElementById(location.hash));
setTimeout(() => {
window.scrollTo({
behavior: element ? "smooth" : "auto",
top: element ? element.offsetTop : 0
});
}, 100);
}, [location]);
returnnull;
};
ScrollHandler.propTypes = {
location: PropTypes.shape({
pathname: PropTypes.string,
search: PropTypes.string,
hash: PropTypes.string,
state: PropTypes.any,
key: PropTypes.string
}).isRequired
};
exportdefaultwithRouter(ScrollHandler);
components/Navigation (links to change url hash history location)
importReactfrom"react";
import { Link } from"react-router-dom";
importListfrom"../List";
constNavigation = () => (
<List>
{[1, 2, 3, 4, 5].map(num => (
<likey={num}><Linkto={`/#section${num}`}>Section {num}</Link></li>
))}
</List>
);
exportdefaultNavigation;
components/Sections (the Headline
component contains the id
that will be matched against)
importReactfrom"react";
importHeadlinefrom"../Headline";
constSections = () =>
[1, 2, 3, 4, 5].map(num => (
<Headlinekey={num}id={`#section${num}`}>
Section {num}
</Headline>
));
exportdefaultSections;
index.js
importReactfrom"react";
import { render } from"react-dom";
import { BrowserRouter } from"react-router-dom";
importContainerfrom"./components/Container";
importNavigationfrom"./components/Navigation";
importSectionsfrom"./components/Sections";
importScrollHandlerfrom"./components/ScrollHandler";
import"./styles.css";
constApp = () => (
<BrowserRouter><Container><ScrollHandler /><Navigation /><Sections /></Container></BrowserRouter>
);
render(<App />, document.getElementById("root"));
Post a Comment for "React Hooks Scroll To Element"