如何设置React Router 6,以便在导航和刷新浏览器窗口时恢复滚动位置?
React Router 5有一个page about scroll restoration,但是我找不到任何关于在the docs for v6中滚动的东西,所以我猜你应该用另一个包自己处理这个问题。很公平,但是我找不到任何与React Router 6兼容的东西。
react-scroll-restoration和oaf-react-router包需要v5版本(oaf-react-router确实列出了它支持v6,但是基本用法代码示例与v6不兼容,并且the related issue #210仍然是开放的)。
Gatsby和Next.js支持开箱即用的滚动恢复,但我看不出有一个 Package 整齐的软件包可以直接使用。
这个小小的demo app with server side rendered pages做了我想要的事情。当来回导航和刷新浏览器窗口时,滚动位置会恢复。
这里是the same app using React Router 6,它的滚动位置不会被保存和恢复,而是在页面之间重用,通常的解决方法是在页面被导航时滚动到顶部,但我对这种行为不感兴趣。
编辑:React Query writes that the issue with scroll restoration is that pages are refetching data,这意味着如果用于呈现页面的数据存在,滚动恢复就可以工作。我不能确认这一点,因为我的小React路由器6应用程序有这个问题,即使没有做任何数据提取。我觉得有一些小的东西,我认为我错过了,以使它工作。
咆哮:我很惊讶,这个问题的典型答案是在导航时调用window.scrollTo(0, 0)
。这只解决了滚动位置在页面之间转移的问题。如果滚动位置没有恢复,用户在页面之间导航的体验就会严重恶化。我想这就是弹出窗口如此流行的部分原因,但它们也带来了一系列其他的UX问题。所以我真的不想用它们。
5条答案
按热度按时间yh2wf1be1#
多亏了oaf-react-router中的这条评论,我才能让它与React Router 6一起工作。不过,有一些警告,所以我不认为这是一个专业Web应用程序的可行解决方案。
1.如代码注解中所述,
oaf-react-router
必须使用与react-router-dom
相同版本的history
。这就是HistoryRouter
被导出为unstable_HistoryRouter
的原因。此解决方案确实感觉相当不稳定。oaf-react-router
在刷新网页时不恢复滚动位置,我不知道这是否容易实现,这是可以接受的。Here a full working example on StackBlitz .
8fsztsew2#
我知道我已经发布了一个答案,但我最终得到了一个不同的解决方案,我认为它值得一个单独的答案。
首先我必须意识到的是StackBlitz和CodeSandbox都有一些自定义的路径处理,会破坏滚动恢复。当在单独的窗口中打开演示应用时,这个问题仍然存在。如果应用在正常环境中运行,使用浏览器的后退和前进按钮在页面之间导航时,滚动位置会恢复。
这两个问题仍然存在:
1.当使用应用程序中的链接导航时,滚动位置在页面之间保持不变。从技术上讲,当使用React Router的
<Link to="..."/>
或navigate(...)
时,页面应滚动到顶部。回顾:转到页面A,向下滚动并单击链接,然后转到页面B。如果使用浏览器的后退按钮导航回A,则滚动位置应恢复。如果使用页面B上的链接导航回A,则滚动位置应位于页面顶部。
1.刷新页面时应恢复(保持)页面的滚动位置,刷新时页面滚动到顶部。
我使用下面的代码解决了第一个问题,并接受了第二个问题仍然是一个问题。我认为Gatsby和Next.js能够通过将滚动位置存储在会话存储中来解决刷新问题,这对我的用例来说感觉有点过头了。
6rqinv9w3#
使用createBrowserHistory并将yscroll存储在会话存储中,可以实现这一点。请参考以下链接:https://medium.com/@knl.shivam.gupta/react-hooks-scroll-position-using-react-router-dom-v6-6cd59730b18d
这里,v6中的location.state用于将yscroll存储在浏览器历史堆栈中,从而可以使用useLayoutEffect操作显示。
aamkag614#
ScrollRestoration
组件处理的正是这个问题。这个组件将模拟加载器完成后浏览器在位置更改时的滚动恢复,以确保滚动位置恢复到正确的位置,即使跨域。
要使用它,只需在应用程序根组件中呈现一次:
xn1cxnb45#
现在,react-router-dom v6.4涵盖了https://dev.to/tywenk/how-to-use-nested-routes-in-react-router-6-4jhd问题