React Router重定向哈希链接

时间:2017-08-24 14:44:08

标签: javascript reactjs react-router

我为自己网站的导航栏创建了一个自定义按钮组件。当用户单击某个按钮时,该组件将返回一个Redirect,将用户带到他们选择的页面。

export default class Button extends Component {
    constructor(props){
        super(props);
        this.state = {redirect:false};
        this._handleClick = this._handleClick.bind(this);
    }

    _handleClick(e) {
        e.stopPropagation();
        this.setState({redirect: true});
    }

    componentDidUpdate() {
        if (this.state.redirect){
            this.setState({redirect:false});
            this.props.onRedirect();
        }
    }

    render() {
        if (this.state.redirect){
            return <Redirect push to={this.props.dest}/>;
        }
        else {
            return (
                <li className="button" onClick={this._handleClick}>
                    <h5>{this.props.text}</h5>
                </li>
            );
        }
    }
}

现在,我想添加与同一页面的不同部分对应的按钮。我所知道的最简单的方法是使用哈希链接。按钮将重定向到的地址的一个示例是:

/home#description

但是,React Router不支持开箱即用。我查看了许多添加此功能的软件包,例如react-router-hash-linkreact-scrollchor。然而,这些都不适用于重定向,而是依赖于Link或自定义组件。

如何将此功能添加到按钮?

6 个答案:

答案 0 :(得分:2)

我可以想到的一种解决方案是使用HOCshooks。最终结果:

  • 您将使您的应用滚动到指定位置...
  • 不需要创建自定义按钮/链接和...
  • 无需对现有屏幕进行太多更改(例如:HomeScreen
  • 奖金:用户可以复制,共享和使用将自动滚动到预期部分的URL


假设下面的代码是伪代码(它们是基于我的知识,未经测试),并且假设有一个HomeScreen组件,我将尝试在{ <Route/>内的{1}}。

<Switch/>


然后:

<Router/>


用法:

<Switch>
  <Route to='/home/:section' component={HomeScreen} />
  <Route to='/home' component={HomeScreen} />
</Switch>


function withScrollToTarget(WrappedComponent) {
  class WithScroll extends React.Component {
    componentDidMount() {
      const { match: { params: { section } } } = this.props
      // Remember we had 2 <Route/>s, so if `section` is provided...
      if (section) {
        const scrollToTarget = document.getElementById(section)
        // And just in case the item was removed or there was an ID mismatch
        if (scrollToTarget) { scrollToTarget.scrollIntoView() }
      }
    }
    render() { return <WrappedComponent {...this.props} /> }
  }
  return WithScroll
}

function useScrollToTarget(section) {
  useEffect(() => {
    if (section) {
      const scrollToTarget = document.getElementById(section)
      if (scrollToTarget) { scrollToTarget.scrollIntoView() }
    }
  }, [section])
}


TLDR:

  • <nav> <Link to='/home'>{'Home'}</Link> <Link to='/home/description'>{'Description'}</Link> </nav> 的路线必须在class HomeScreen extends React.Component { /* ... */ } export default withScrollToTarget(HomeScreen) // or function HomeScreen() { const { params: { section } } = useMatch() // from react-router-dom useScrollTotarget(section) return ( <div> <h1 id='introduction'>Introduction</h1> <h1 id='description'>Description</h1> </div> ) } 的顶部。如果相反,则每次'/home/:section'将当前URL与'/home'进行比较时,到达<Switch/>时它将评估为to,而从未到达true
  • '/home'是一项合法功能
  • 如果这对您有用,那么您还应该查看如何在HOC中转发引用和提升静力学

答案 1 :(得分:1)

谁说React Router确实支持此功能!您不需要那些软件包。您可以重定向哈希,我将使用React-Router路由为您提供示例。

<Route
  exact
  path="/signup"
  render={props => {
    if (props.location.hash === "#foo")
      return <Redirect push to="signup#bar"
    return <Signup />
  }}
/>

现在,考虑到您的版本现在可能不支持此功能,但是请告诉我这是否有帮助:) 编码愉快!

答案 2 :(得分:0)

您可以更新window.location.href,因为它不会触发页面刷新。

例如

window.location.href = '#your-anchor-tag';

答案 3 :(得分:0)

React-hash-link应该适用于您的重定向用例。

您可以将<HashLinkObserver />添加到组件树中,它将侦听哈希链接并进行相应的滚动,而不必依赖Link或自定义组件。

答案 4 :(得分:0)

我认为您应该使用react-router-dom。

import React from 'react';
import { withRouter } from "react-router-dom";
class Button extends Component {
    constructor(props){
        super(props);
        this.state = {redirect:false};
        this._handleClick = this._handleClick.bind(this);
    }

    _handleClick(e) {
        e.stopPropagation();
        this.setState({redirect: true});
    }

    componentDidUpdate() {
        if (this.state.redirect){
            this.setState({redirect:false});
            //this.props.onRedirect();
            this.props.history.push('new uri');
        }
    }

    render() {
        if (this.state.redirect){
            return <Redirect push to={this.props.dest}/>;
        }
        else {
            return (
                <li className="button" onClick={this._handleClick}>
                    <h5>{this.props.text}</h5>
                </li>
            );
        }
    }
}
export default withRouter(Button);

现在更新这样的自定义按钮组件

{{1}}

答案 5 :(得分:0)

我遇到了同样的问题,我创建了HOC来处理哈希重定向,您可以按照以下步骤实现哈希重定向

  1. 创建HOC并向其中添加以下代码

fileName:hashComponent

import React, { useEffect } from 'react';

export default function hashComponent(WrappedComponent) {

  return function () {
    const { pathname, hash }=window.location;
    useEffect(() => {

      if(hash)
        window.location.href=`${pathname}${hash}`;
    }, [hash])

    return <WrappedComponent />
  }
}
  1. 将您的HOC导入到您想要处理哈希URL的组件中

  2. 然后在导出组件时添加以下代码行

    导出默认的hashComponent(YourComponentName)