【问题标题】:Using anchor tags in react-router 4在 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 商店中看到哈希锚标签,它确实导航到新路线,但它不会向下滚动到标签本身。

是否由我来创建滚动功能,或者它应该如何工作?

【问题讨论】:

    标签: javascript reactjs react-router


    【解决方案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';

    【讨论】:

    • 然而值得注意的是,在这种情况下,只需使用标准的&lt;a&gt; 链接就可以轻松避免这种情况。 React-Router &lt;Link&gt; 不是必需的,因为如果您在同一页面中导航,则无需在此处进行组件操作。因此,标准的&lt;a&gt; 链接可以被认为是最佳解决方案,它不需要安装其他软件包等。但是,如果您需要导航到另一个“页面”上的哈希链接,那么是的,这个软件包就是解决方案。跨度>
    【解决方案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

    【讨论】:

    • 我搞砸了&lt;a&gt;&lt;Link&gt;&lt;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 - 这不是用于切换路线,而是用于在不刷新路线的情况下滚动到页面上的某个位置。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-03-13
        • 2020-04-27
        • 2018-05-20
        • 2017-03-09
        • 1970-01-01
        • 2015-05-07
        相关资源
        最近更新 更多