react-router切换页面后跳转到页面顶部

在使用react-router做路由的时候,会发现如果直接使用,当你采用一些特殊的overflow元素时,会发现切换页面后scrollbar在原位不动,这导致一些不好的体验,因为用户切换界面常常是要查看全新的内容。之所以产生这个问题,很大的原因是virtual dom带来的负面影响。virtual dom仅利用数据对要生成的dom结构做diff计算,只更新那些改变了的元素。而react-router带来的结果是,仅route内部组件的部分节点发生了变化。所以,对于有scrollbar的那个元素而言,没有变动,scrollbar的位置也不会改变。

解决的办法是创建一个container组件,在这个组件中去执行dom操作,让scrollbar跳转到顶部去:

import { withRouter } from "react-router-dom";
class ScrollToTop extends Component {
    componentDidUpdate(prevProps) {
        if (this.props.location.pathname !== prevProps.location.pathname) {
            document.getElementById("page").scrollTo(0, 0);
        }
    }
    render() {
        return this.props.children;
    }
}
const PageContainer = withRouter(ScrollToTop);
// ... 下面是渲染部分 ...
<Router>
  <PageContainer>
    {/* 你的正常的渲染内容 */}
  </PageContainer>
</Router>

解决的方法非常简单,就是在Router下面再放一个根性质的组件,Router会给下面的组件传递location, match等props,所以,可以在这个组件里面进行监听,通过判断来决定是否要执行scrollTo(0, 0)这样的操作。上面红色的部分则是需要自己进行修改,甚至,你可以把这个组件进行丰富,根据你的项目需要来决定什么时候要跳,哪些元素要跳。