我为自己网站的导航栏创建了一个自定义按钮组件。当用户单击某个按钮时,该组件将返回一个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-link和react-scrollchor。然而,这些都不适用于重定向,而是依赖于Link
或自定义组件。
如何将此功能添加到按钮?
答案 0 :(得分:2)
我可以想到的一种解决方案是使用HOCs和hooks。最终结果:
HomeScreen
)
假设下面的代码是伪代码(它们是基于我的知识,未经测试),并且假设有一个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'
是一项合法功能答案 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来处理哈希重定向,您可以按照以下步骤实现哈希重定向
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 />
}
}
将您的HOC导入到您想要处理哈希URL的组件中
然后在导出组件时添加以下代码行
导出默认的hashComponent(YourComponentName)