簡體   English   中英

反應路由器重定向哈希鏈接

[英]React Router redirect hash link

我為我網站的導航欄創建了一個自定義按鈕組件。 當用戶點擊按鈕時,組件返回一個重定向,將用戶帶到他們選擇的頁面。

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或自定義組件。

如何將此功能添加到按鈕?

您可以更新window.location.href因為它不會觸發頁面刷新。

例如

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

誰說 React Router 不支持開箱即用! 你不需要那些包。 你可以重定向一個哈希,我會給你一個使用 React-Router Route 的例子。

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

現在我考慮一下,現在您的版本可能不支持此功能,但是如果這有幫助,請告訴我:) 編碼愉快!

我能想到的一種解決方案是使用HOCshooks 最終結果:

  • 你會讓你的應用滾動到指定的位置......
  • 無需創建自定義按鈕/鏈接和...
  • 無需對現有屏幕進行太多更改(例如: HomeScreen
  • 獎勵:用戶可以復制、共享和使用會自動滾動到預期部分的 URL


假設下面的代碼是偽代碼(它們基於我的知識並且未經測試)並假設有一個HomeScreen組件,我會嘗試將<Route/>添加到<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])
}


用法:

<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'的路由必須在'/home'之上。 如果相反,每次<Switch/>將當前 URL 與to進行比較時,它會在到達'/home'時評估為true並且永遠不會到達'/home/:section'
  • scrollIntoView()是一個合法的函數
  • 如果這對你有用,你也應該看看如何在 HOC 中轉發引用和提升靜態

React-hash-link應該適用於您的重定向用例。

您可以將<HashLinkObserver />添加到您的組件樹中,它將偵聽哈希鏈接並相應地滾動,而不是依賴於Link或自定義組件。

我認為您應該使用 react-router-dom。

yarn add 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);

我遇到了同樣的問題,我創建了 HOC 來處理哈希重定向,您可以按照以下步驟實現哈希重定向

  1. 創建 HOC 並向其添加以下代碼

文件名:哈希組件

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. 在要處理哈希 URL 的組件中導入您的 HOC

  2. 然后在導出組件時添加以下代碼行

    導出默認 hashComponent(YourComponentName)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM