reactjs - 人们如何使用 React-router v4 处理滚动恢复?

标签 reactjs react-router

使用 react 路由器时,我在后退按钮(历史弹出状态)上的滚动位置遇到一些问题。 React router v4 不处理开箱即用的滚动管理,因为浏览器正在实现一些自动滚动行为。这很好,除非浏览器窗口的高度从一个 View 到另一个 View 变化太大。我已经实现了 ScrollToTop 组件,如下所述:https://reacttraining.com/react-router/web/guides/scroll-restoration

这很好用。当您单击链接并转到不同的组件时,浏览器会滚动到顶部(就像普通的服务器渲染网站一样)。仅当您返回(通过浏览器后退按钮)到窗口高度更高的 View 时,才会出现此问题。似乎(chrome)尝试在react渲染内容(和浏览器高度)之前转到上一页的滚动位置。这会导致滚动仅根据其来自的 View 的高度尽可能向下移动。想象一下这个场景:

View1:长长的电影列表(窗口高度 3500 像素)。
(点击电影)
View2:所选电影的详细信息 View (窗口高度:1000px)。
(单击浏览器后退按钮)
返回 View 1,但滚动位置不能超过 1000px,因为 chrome 试图在 React 渲染长电影列表之前设置位置。

出于某种原因,这只是 Chrome 中的一个问题。 Firefox 和 Safari 似乎处理得很好。我想知道是否还有其他人遇到过这个问题,以及你们通常如何处理 React 中的滚动恢复。

注意:所有电影都是从 exampleMovies.js 导入的 - 因此在我的示例中我不会等待 API 响应。

最佳答案

请注意,history.scrollRestoration只是禁用浏览器自动尝试滚动恢复的一种方法,这对于单页应用程序来说大多不起作用,因此它们不会干扰任何内容该应用程序想做的事。除了切换到手动滚动恢复之外,您还需要某种库来提供浏览器历史记录 API、React 渲染以及窗口和任何可滚动 block 元素的滚动位置之间的集成。

在无法找到 React Router 4 这样的滚动恢复库后,我创建了一个名为 react-scroll-manager 的库。 。它支持在导航到新位置时滚动到顶部(也称为历史推送)和后退/前进滚动恢复(又称为历史弹出)。除了滚动窗口之外,它还可以滚动您包装在 ElementScroller 组件中的任何嵌套元素。它还通过使用 MutationObserver 支持延迟/异步渲染。在用户指定的时间限制内观看窗口/元素内容。这种延迟渲染支持适用于滚动恢复以及使用哈希链接滚动到特定元素。

npm 安装react-scroll-manager

import React from 'react';
import { Router } from 'react-router-dom';
import { ScrollManager, WindowScroller, ElementScroller } from 'react-scroll-manager';
import { createBrowserHistory as createHistory } from 'history';

class App extends React.Component {
  constructor() {
    super();
    this.history = createHistory();
  }
  render() {
    return (
      <ScrollManager history={this.history}>
        <Router history={this.history}>
          <WindowScroller>
            <ElementScroller scrollKey="nav">
              <div className="nav">
                ...
              </div>
            </ElementScroller>
            <div className="content">
              ...
            </div>
          </WindowScroller>
        </Router>
      </ScrollManager>
    );
  }
}

请注意,需要 HTML5 浏览器(IE 10+)和 React 16。 HTML5 提供历史 API,并且该库使用 React 16 中的现代 Context 和 Ref API。

关于reactjs - 人们如何使用 React-router v4 处理滚动恢复?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44970279/

相关文章:

reactjs - 为什么在链接到我的组件后没有调用 mapDispatchToProps?

reactjs - 无法读取未定义的属性 ‘params’ (React Router 4)

reactjs - 来自react-router-redux的 "push"方法和来自react-router的 "browserHistory"有什么区别?

javascript - 运行一次查询后按钮禁用

javascript - Expo React Native App 不再显示图表

javascript - reactjs 组件上的 405(方法不允许)

javascript - 结合两个mapStateToProps React

javascript - 只有一个使用 react-grid-layout 的 highcharts 可以调整大小

javascript - React-router - 组件在父组件状态更改时重新加载?

reactjs - 未找到页面已返回