I want the page to scroll down to my anchor tags when a user navigates to it through an anchor link.
I'm using react-router 4 and I've defined things as follows:
navbar:
export default (props) => {
const {
updateModal,
updateRoute,
} = props
return(
<Navbar fluid collapseOnSelect>
<Nav>
<NavDropdown eventKey="4" title="Solutions" id="nav-dropdown" noCaret>
<MenuItem eventKey="4.1">
<Link to='/solution#ipos'>TESTING ANCHOR</Link>
</MenuItem>
...
some route:
export default class extends Component {
constructor() {
super()
this.state = {
isLoading: true
}
}
render() {
return (
<Grid className='solutions' fluid>
<Row className='someClass'>
<div>
<h2><a href='ipos' id='ipos'>Ipos morna santos paros</a></h2>
...
I can see the hash anchor tag in the url and in my redux store when I click on the anchor link in the navebar, and it indeed navigates to the new route, but it doesn't scroll down to the tag itself.
Is it up to me to create the scroll function or how is it supposed to work exactly?
To scroll down to your anchor tags, you need to install React Router Hash Link, with:
npm install --save react-router-hash-link
then import Hash Link:
import { HashLink as Link } from 'react-router-hash-link';
and then use Hash Link, for example:
<Link to="/pathLink#yourAnchorTag">Your link text</Link>
and at the destination component, for example:
<div id= "yourAnchorTag">
<p>Linked to here<p>
</div>
It is a known issue with react router. ( https://github.com/ReactTraining/react-router/issues/394#issuecomment-220221604 )
There is a solution as well. https://www.npmjs.com/package/react-router-hash-link this package solves the issue.
You have to use this Hash Link
as the Link
like below.
import { HashLink as Link } from 'react-router-hash-link';
If you have only few predictable anchor links, the simplest way to achieve the normal behavior is to manually scrollIntoView()
of the element if you have the expected anchor tag in the Window.location.href
.
class Page extends react.Component {
componentDidMount() {
if (this.$ref && location.href.includes('#my-ref')) {
this.$ref.scrollIntoView({
// optional params
behavior: 'smooth',
block: 'start',
inline: 'center',
});
}
}
render() {
return (
// This is the div you want to scroll to
<div ref={ref => {
this.$ref = ref;
}}>
Other content
</div>
);
}
}
Check Element.scrollIntoView() and React refs .
You can pass an object to Link, like this
<Link
to={{
pathname: "/courses",
search: "?sort=name",
hash: "#the-hash",
state: { fromDashboard: true }
}}
/>
Similar to @filippo, but with React hooks and a little Typescript.
import React, { Functioncomponent, useEffect, useRef } from 'react'; import { useLocation } from 'react-router-dom'; const MyFunc: FunctionComponent = () => { const myRef = useRef<null | HTMLDivElement>(null); useEffect(() => { if (myRef && location.hash.includes('#my-ref')) { myRef?.current?.scrollIntoView({ behavior: 'smooth', block: 'start', inline: 'center' }); } }, [myRef, location.hash]); return ( <div> Some stuff before </div> <div ref={myRef}> Scroll to me </div> <div> Some stuff after </div> ) } export default MyFunc;
I was using Gatsby, and my solution was to use @reach/router
in the form:
import { navigate } from '@reach/router';
navigate('#some-link');
An alternative to using hash fragments in anchor tags is to query the DOM and use scrollIntoView()
as part of the onClick
event.
function handleClick(evt) {
...
document.querySelector('[id="label-input-1"]').scrollIntoView();
}
...
<a href={''} onClick={e => handleClick(e)}>Foo</a>
This just bypasses the routers refreshing of the page when the window location updates with the hash address.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.