在react router v4中,如何链接到片段标识符?

Chr*_*ris 15 javascript reactjs react-router

鉴于非常简单的页面(假设已经导入了React和react-router @ 4):

// Current location: example.com/about
<Link to="/about/#the-team">See the team</Link>
// ... loads of content ... //
<a id="the-team"></a>
Run Code Online (Sandbox Code Playgroud)

我希望上面的内容,点击"看到团队"后会向下滚动到id'ed团队主播.网址正确更新为:example.com/about#the-team,但不会向下滚动.

我尝试了其他替代品,<a name="the-team"></a>但我相信这不再是规范(也不适用).

在github上有很多关于react-router @ v2的解决办法,但它们依赖于BrowserRouter上存在的更新回调,v4中不再存在.

Pau*_*l S 15

给定一个<ScrollIntoView>组件,它将元素的id滚动到:

class ScrollIntoView extends React.Component {

  componentDidMount() {
    this.scroll()
  }

  componentDidUpdate() {
    this.scroll()
  }

  scroll() {
    const { id } = this.props
    if (!id) {
      return
    }
    const element = document.querySelector(id)
    if (element) {
      element.scrollIntoView()
    }
  }

  render() {
    return this.props.children
  }
}
Run Code Online (Sandbox Code Playgroud)

您可以将视图组件的内容包装在其中:

const About = (props) => (
  <ScrollIntoView id={props.location.hash}>
    // ...
  </ScrollIntoView>
)
Run Code Online (Sandbox Code Playgroud)

或者你可以创建一个匹配包装器:

const MatchWithHash = ({ component:Component, ...props }) => (
  <Match {...props} render={(props) => (
    <ScrollIntoView id={props.location.hash}>
      <Component {...props} />
    </ScrollIntoView>
  )} />
)
Run Code Online (Sandbox Code Playgroud)

用法是:

<MatchWithHash pattern='/about' component={About} />
Run Code Online (Sandbox Code Playgroud)

一个完全充实的解决方案可能需要考虑边缘情况,但我做了上面的快速测试,它似乎工作.

编辑:

此组件现在可通过npm获得

npm install --save rrc

import { ScrollIntoView } from 'rrc'
Run Code Online (Sandbox Code Playgroud)