在 react-router 4 中使用锚标签
Posted
技术标签:
【中文标题】在 react-router 4 中使用锚标签【英文标题】:Using anchor tags in react-router 4 【发布时间】:2018-06-21 18:09:54 【问题描述】:当用户通过锚链接导航到页面时,我希望页面向下滚动到我的锚标记。
我正在使用 react-router 4,我已经定义如下:
导航栏:
export default (props) =>
const
updateModal,
updateRoute,
= props
return(
<Navbar fluid collapseOnSelect>
<Nav>
<NavDropdown eventKey="4" title="Solutions" id="nav-dropdown" noCaret>
<MenuItem eventKey="4.1">
<Link to='/solution#ipos'>TESTING ANCHOR</Link>
</MenuItem>
...
一些路线:
export default class extends Component
constructor()
super()
this.state =
isLoading: true
render()
return (
<Grid className='solutions' fluid>
<Row className='someClass'>
<div>
<h2><a href='ipos' id='ipos'>Ipos morna santos paros</a></h2>
...
当我单击导航栏中的锚链接时,我可以在 url 和我的 redux 商店中看到哈希锚标签,它确实导航到新路线,但它不会向下滚动到标签本身。
是否由我来创建滚动功能,或者它应该如何工作?
【问题讨论】:
【参考方案1】:这是 react 路由器的一个已知问题。 (https://github.com/ReactTraining/react-router/issues/394#issuecomment-220221604)
也有解决办法。 https://www.npmjs.com/package/react-router-hash-link这个包解决了这个问题。
你必须像下面这样使用Hash Link
作为Link
。
import HashLink as Link from 'react-router-hash-link';
【讨论】:
然而值得注意的是,在这种情况下,只需使用标准的<a>
链接就可以轻松避免这种情况。 React-Router <Link>
不是必需的,因为如果您在同一页面中导航,则无需在此处进行组件操作。因此,标准的<a>
链接可以被认为是最佳解决方案,它不需要安装其他软件包等。但是,如果您需要导航到另一个“页面”上的哈希链接,那么是的,这个软件包就是解决方案。跨度>
【参考方案2】:
要向下滚动到您的锚标记,您需要安装React Router Hash Link,其中:
npm install --save react-router-hash-link
然后导入哈希链接:
import HashLink as Link from 'react-router-hash-link';
然后使用Hash Link,例如:
<Link to="/pathLink#yourAnchorTag">Your link text</Link>
在目标组件处,例如:
<div id= "yourAnchorTag">
<p>Linked to here<p>
</div>
【讨论】:
很难相信在这个包之外还没有更常见的做法。看起来真的很奇怪。 2020 年 2 月报告,这仍然是最好的方法(遗憾) 实际上我什至无法让它按预期运行。这个框架有时会让人大失所望。我有一个永远不会改变的静态 ID 的元素,我要做的就是添加一个 a[href="#myAnchor"] 并滚动到它。如果没有至少 20 行代码,这似乎是不可能的。 这对我来说也很有趣,这个 SO 答案是唯一一个提供了如何编写你链接的东西的例子的答案。谢谢@Adrian【参考方案3】:如果您只有几个可预测的锚链接,实现正常行为的最简单方法是手动 scrollIntoView()
元素如果您在 Window.location.href
中有预期的锚标记。
class Page extends react.Component
componentDidMount()
if (this.$ref && location.href.includes('#my-ref'))
this.$ref.scrollIntoView(
// optional params
behavior: 'smooth',
block: 'start',
inline: 'center',
);
render()
return (
// This is the div you want to scroll to
<div ref=ref =>
this.$ref = ref;
>
Other content
</div>
);
检查Element.scrollIntoView() 和React refs。
【讨论】:
我搞砸了<a>
、<Link>
和<HashLink
,但没有一个能正常工作——它们都会刷新页面并可能滚动到正确的位置。这只是通过滚动到正确的位置减去刷新来工作
非常有帮助,谢谢。一个小的修正。参数behaviour
应该是behavior
;)【参考方案4】:
类似于@filippo,但带有 React 钩子和一点 Typescript。
import React, Functioncomponent, useEffect, useRef from 'react';
import useLocation from 'react-router-dom';
const MyFunc: FunctionComponent = () =>
const myRef = useRef<null | htmlDivElement>(null);
useEffect(() =>
if (myRef && location.hash.includes('#my-ref'))
myRef?.current?.scrollIntoView(
behavior: 'smooth',
block: 'start',
inline: 'center'
);
, [myRef, location.hash]);
return (
<div> Some stuff before </div>
<div ref=myRef> Scroll to me </div>
<div> Some stuff after </div>
)
export default MyFunc;
【讨论】:
【参考方案5】:你可以将一个对象传递给 Link,像这样
<Link
to=
pathname: "/courses",
search: "?sort=name",
hash: "#the-hash",
state: fromDashboard: true
/>
参考。 https://reacttraining.com/react-router/web/api/Link
【讨论】:
这很有帮助。【参考方案6】:我使用的是 Gatsby,我的解决方案是使用 @reach/router
的形式:
import navigate from '@reach/router';
navigate('#some-link');
Link to Gatsby documentation.
【讨论】:
【参考方案7】:在锚标记中使用散列片段的另一种方法是查询 DOM 并使用scrollIntoView()
作为onClick
事件的一部分。
function handleClick(evt)
...
document.querySelector('[id="label-input-1"]').scrollIntoView();
...
<a href='' onClick=e => handleClick(e)>Foo</a>
这只是在窗口位置使用哈希地址更新时绕过路由器刷新页面。
【讨论】:
这里的问题是当你切换到另一个路由并且dom还没有完全加载时,函数将找不到锚点,因此不会滚动到它。您将不得不等待组件完全加载 @JonasMerhej - 这不是用于切换路线,而是用于在不刷新路线的情况下滚动到页面上的某个位置。以上是关于在 react-router 4 中使用锚标签的主要内容,如果未能解决你的问题,请参考以下文章