在 react-router 4 中使用锚标签

IT技术 javascript reactjs react-router
2021-02-20 16:15:09

当用户通过锚链接导航到页面时,我希望页面向下滚动到我的锚标签。

我正在使用 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 商店中看到哈希锚标记,并且它确实导航到新路由,但它不会向下滚动到标记本身。

是由我来创建滚动功能还是它应该如何工作?

6个回答

要向下滚动到您的锚点标签,您需要安装React Router Hash Link,使用:

npm install --save react-router-hash-link

然后导入哈希链接:

import { HashLink as Link } from 'react-router-hash-link';

然后使用哈希链接,例如:

<Link to="/pathLink#yourAnchorTag">Your link text</Link>

在目标组件,例如:

<div id= "yourAnchorTag">
      <p>Linked to here<p>
</div>
实际上,我什至无法让它按预期运行。这个框架有时会让人大失所望。我有一个静态 ID 永远不会改变的元素,我想要做的就是添加一个 a[href="#myAnchor"] 并滚动到它。如果没有至少 20 行代码,这似乎是不可能的。
2021-04-19 16:15:09
2020 年 2 月报告,这仍然是最好的方法(遗憾)
2021-04-28 16:15:09
很难相信在这个包之外还不存在更常见的做法。看起来真的真的很奇怪。
2021-05-06 16:15:09
我也很有趣的是,这个 SO 答案是唯一一个提供了如何编写您要链接到的事物的示例的答案。谢谢@阿德里安
2021-05-09 16:15:09

这是react-router的一个已知问题。( 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>链接可以被认为是最佳解决方案,它不需要安装其他软件包等。但是,如果您需要导航到另一个“页面”上的哈希链接,那么是的,这个软件包将是解决方案。
2021-04-20 16:15:09

如果您只有几个可预测的锚链接,实现正常行为的最简单方法是手动删除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并且没有一个工作正常 - 他们都会刷新页面并且可能滚动到正确的位置。这只是通过滚动到正确的位置减去刷新
2021-05-08 16:15:09
很有帮助,谢谢。一个小的修正虽然。参数behaviour应该是behavior;)
2021-05-15 16:15:09

您可以像这样将对象传递给 Link

<Link
  to={{
    pathname: "/courses",
    search: "?sort=name",
    hash: "#the-hash",
    state: { fromDashboard: true }
  }}
/>

参考 https://reacttraining.com/react-router/web/api/Link

这很有帮助。
2021-05-15 16:15:09

类似于@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;