Reputation: 3415
I'm using React Router 4 and when I use <Link>
the new page doesn't open at the top of the page. Do I need to tell <Link>
something specific?
<Link to="/mypage">My Page</Link>
Upvotes: 14
Views: 23204
Reputation: 446
v6: if you don't want to use a side effect you can do something like this
// ScrollLink.ts
import React from 'react';
import {Link, LinkProps} from "react-router-dom";
const ScrollLink = React.forwardRef<HTMLAnchorElement, LinkProps>((props, ref) => {
return <Link {...props} ref={ref} onClick={() => window.scrollTo(0, 0)}/>
});
export default ScrollLink;
and then use ScrollLink
wherever you want to scroll on click
Upvotes: 1
Reputation: 937
I know my answer might be similar as previous but I just want to help those who are using React Hooks and might come across this question/answers...
useLayoutEffect(() => {
window.scrollTo(0, 0)
});
Basically, what I mean is that, add window.scrollTo(0, 0)
inside the useLayoutEffect
and will work fine.
Upvotes: 26
Reputation: 711
To go back to the What I did is when my Compoenent inside my BrowserRouter Updates I send it back to the top with the window props like this :
Root.jsx :
...
<BrowserRouter onUpdate={() => window.scrollTo(0, 0)} >
<Switch>
<Route exact path={path.LOGIN} render={Login} />
<Route exact path={path.SIGNUP} render={Signup} />
<Route
path={path.HOMEPAGE}
render={() => <HomePageRouter />}
/>
</Switch>
</BrowserRouter>
...
And Then in my HomePageRouter
class HomePageRouter extends Component {
componentDidUpdate() {
window.scrollTo(0, 0);
}
render() {
return (
<div className='bm-page-wrapper' >
<NavBar
activeItem={this.props.menu.activeItem}
toggle={this.props.menu.toggle}
lang={this.props.lang}
/>
<Switch >
<Route
exact
path={path.HOMEPAGE}
render={() => <Homepage lang={this.props.lang} />}
/>
<Route
path={path.ABOUT}
render={() => <About lang={this.props.lang} />}
/>
<Route
path={path.CONTACT}
render={() => <Contact lang={this.props.lang} />}
/>
<Route render={() => <NotFound lang={this.props.lang} />} />
</Switch>
<Footer lang={this.props.lang} />
</div>
);
}
}
So any path that I go in my HomePageRouter component, it will detect a route update and will cause it to re render. I would recommand using some sub Router so you don't have to add componentDidUpdate(){...} on every component !
Hopes it helps !
Upvotes: 0
Reputation: 566
I found a pretty solid answer for this in the answer to a similar question. It worked for me anyway so I thought I would share.
For your situation, in the component for "/mypage" add window.scrollTo(0, 0);
to the componentDidMount function. Something like this:
import ...
export default class MyPage extends Component {
constructor(props) {
super(props);
this.state = {
...
};
}
componentDidMount() {
window.scrollTo(0, 0);
}
render() {
return (
...
)
}
}
The Link component will handle navigating to the new path and once the new component is mounted, it will automatically scroll to the top.
Upvotes: 21
Reputation: 1252
So I found one pretty cool fix for this. Basically you will need to create a wrapper component (it will wrap Route) that will be responsible only for scrolling to the top. You will then need to use the wrapper instead of route in your router than. The complete solution is here: react-router scroll to top on every transition
Scroll down to where it says: For react-router v4
P.S. make sure you have the object-rest-spread configured in your .babelrc. Here is a link for that:
https://babeljs.io/docs/plugins/transform-object-rest-spread/
Upvotes: 7