添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
首发于 银匠屋

【React开发定式】返回自动滚动到上次浏览位置

我是銀桑,希望能帮到你。

一句话总结

通过Route内的一个定制组件来记录当前页面滚动位置,在实际页面渲染完后的恰当时机,通过context执行滚动到记录位置的函数。

缘起

在使用React Router的项目开发中,返回时定位到上次浏览位置是非常常见的交互,而官方并没有明确应该如何实现。

原理介绍

以最常见的HashRouter为例,

<HashRouter>
   <PageIndex/>
</HashRouter>

在PageIndex外包一层组件ScrollToPosition 用来记录窗口的位置。则有了以下代码。

ReactDOM.render(
  <HashRouter >
    <ScrollToPosition>
      {renderRoutes(routesConfig)}
    </ScrollToPosition>
  </HashRouter>
  document.getElementById('app')
);

ScrollToPosition的代码如下

import React, { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
import _ from 'lodash'
import { PageScrollContext } from '@/components/context';
const ScrollToPosition = ({ children }) => {
  const location = useLocation();
  const { pathname } = location;
  const scrollTo = () => {
    const scrollY = sessionStorage.getItem(pathname);
    // 为了避免scrollY为0引起的滚动到顶部后没有记录的bug,将交互改为在150px内直接滚动到顶部
    if (scrollY) {
      const scrollResult = Number(scrollY) < 150 ? 0 : Number(scrollY);
      window.scrollTo(0, scrollResult);
  // 路由切换时重新绑定一次最新的pathname
  useEffect(() => {
    const scrollHandler = util.throttle(() => {
      // 点击切换路由时会触发一次scroll,此时 scrollY为0
      if (window.scrollY > 0) {
        sessionStorage.setItem(pathname, String(window.scrollY));
    window.addEventListener('scroll', scrollHandler);
    return () => {
      // 做好清理
      window.removeEventListener('scroll', scrollHandler);
  }, [pathname]);
  return (
    <PageScrollContext.Provider value={scrollTo}>
      {children}
    </PageScrollContext.Provider>
export default ScrollToPosition;

context 自然就定义如下

export const PageScrollContext = React.createContext(() => {});

因一般页面是根据接口渲染,所以需要在合适的时机调用PageScrollContext对应的函数。

import { PageScrollContext } from '@/components/context';