[英]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-link和react-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 />
}}
/>
現在我考慮一下,現在您的版本可能不支持此功能,但是如果這有幫助,請告訴我:) 編碼愉快!
我能想到的一種解決方案是使用HOCs和hooks 。 最終結果:
HomeScreen
)
假設下面的代碼是偽代碼(它們基於我的知識並且未經測試)並假設有一個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()
是一個合法的函數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 來處理哈希重定向,您可以按照以下步驟實現哈希重定向
文件名:哈希組件
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 />
}
}
在要處理哈希 URL 的組件中導入您的 HOC
然后在導出組件時添加以下代碼行
導出默認 hashComponent(YourComponentName)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.