通过react-router
我可以使用Link
元素来创建由react路由器本地处理的链接。
我在内部看到它调用this.context.transitionTo(...)
。
我想从下拉列表中进行导航,而不是从链接进行导航。 如何在代码中执行此操作? 这是什么this.context
?
我看到了Navigation
混合器,但是没有混合器可以做到吗?
#1楼
React-Router 5.1.0+答案(使用钩子和React> 16.8)
您可以在功能组件上使用新的useHistory
钩子,并以编程方式导航:
import { useHistory } from "react-router-dom";
function HomeButton() {
let history = useHistory();
// use history.push('/some/path') here
};
React-Router 4.0.0+答案
在4.0及更高版本中,将历史记录用作组件的支持。
class Example extends React.Component {
// use `this.props.history.push('/some/path')` here
};
注意:如果您的组件不是由<Route>
呈现的,则this.props.history不存在。 您应该使用<Route path="..." component={YourComponent}/>
在YourComponent中包含this.props.history
React-Router 3.0.0+答案
在3.0及更高版本中,将路由器用作组件的支持。
class Example extends React.Component {
// use `this.props.router.push('/some/path')` here
};
React-Router 2.4.0+答案
在2.4及更高版本中,使用高阶组件将路由器作为组件的道具。
import { withRouter } from 'react-router';
class Example extends React.Component {
// use `this.props.router.push('/some/path')` here
};
// Export the decorated class
var DecoratedExample = withRouter(Example);
// PropTypes
Example.propTypes = {
router: React.PropTypes.shape({
push: React.PropTypes.func.isRequired
}).isRequired
};
React-Router 2.0.0+答案
该版本与1.x向后兼容,因此不需要升级指南。 仅通过示例就足够了。
也就是说,如果您希望切换到新模式,则路由器内有一个browserHistory模块,您可以通过该模块访问
import { browserHistory } from 'react-router'
现在您可以访问浏览器历史记录,因此您可以执行推,替换等操作,例如:
browserHistory.push('/some/path')
React-Router 1.xx答案
我不会介绍升级细节。 您可以在《 升级指南》中阅读有关内容
关于此问题的主要更改是从Navigation mixin到History的更改。 现在,它使用浏览器historyAPI更改路由,因此从现在开始我们将使用pushState()
。
这是使用Mixin的示例:
var Example = React.createClass({
mixins: [ History ],
navigateToHelpPage () {
this.history.pushState(null, `/help`);
}
})
请注意,此“ History
来自“ 球拍/历史记录”项目。 不是来自React-Router本身。
如果由于某种原因(也许由于ES6类)不想使用Mixin,则可以从this.props.history
访问从路由器获得的历史记录。 仅路由器提供的组件可以访问它。 因此,如果要在任何子组件中使用它,则需要通过props
将其作为属性向下传递。
您可以在其1.0.x文档中了解有关新版本的更多信息。
它建议获取参考history = createHistory()
并在其上调用replaceState
。
React-Router 0.13.x答案
我遇到了同样的问题,只能使用react-router附带的Navigation mixin找到解决方案。
这是我做的
import React from 'react';
import {Navigation} from 'react-router';
let Authentication = React.createClass({
mixins: [Navigation],
handleClick(e) {
e.preventDefault();
this.transitionTo('/');
},
render(){
return (<div onClick={this.handleClick}>Click me!</div>);
}
});
我无需调用.context
就可以调用transitionTo()
或者您可以尝试精美的ES6 class
import React from 'react';
export default class Authentication extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick(e) {
e.preventDefault();
this.context.router.transitionTo('/');
}
render(){
return (<div onClick={this.handleClick}>Click me!</div>);
}
}
Authentication.contextTypes = {
router: React.PropTypes.func.isRequired
};
React-Router-Redux
注意:如果您使用Redux,还有另一个名为React-Router-Redux的项目,它使用与React-Redux相同的方法为您提供ReactRouter的redux绑定。
React-Router-Redux有几种可用的方法,这些方法允许从内部动作创建者进行简单导航。 这些对于在React Native中具有现有架构的人特别有用,并且他们希望以最小的模板开销在React Web中使用相同的模式。
探索以下方法:
-
push(location)
-
replace(location)
-
go(number)
-
goBack()
-
goForward()
这是Redux-Thunk的用法示例:
./actioncreators.js
import { goBack } from 'react-router-redux'
export const onBackPress = () => (dispatch) => dispatch(goBack())
./viewcomponent.js
<button
disabled={submitting}
className="cancel_button"
onClick={(e) => {
e.preventDefault()
this.props.onBackPress()
}}
>
CANCEL
</button>
#2楼
警告:此答案仅涵盖1.0之前的ReactRouter版本
之后,我将以1.0.0-rc1用例更新此答案!
您也可以不使用mixins。
let Authentication = React.createClass({
contextTypes: {
router: React.PropTypes.func
},
handleClick(e) {
e.preventDefault();
this.context.router.transitionTo('/');
},
render(){
return (<div onClick={this.handleClick}>Click me!</div>);
}
});
带有上下文的陷阱是,除非您在类上定义contextTypes
,否则无法访问它。
至于什么是上下文,它是一个像道具一样的对象,它从父级传递到子级,但是隐式地传递下来,而不必每次都重新声明道具。 参见https://www.tildedave.com/2014/11/15/introduction-to-contexts-in-react-js.html
#3楼
React-路由器v2
对于最新版本( v2.0.0-rc5
),推荐的导航方法是直接推送到历史单例。 您可以在Components doc之外的导航中看到这一点。
相关摘录:
import { browserHistory } from 'react-router';
browserHistory.push('/some/path');
如果使用较新的react-router API,则需要在组件内部使用this.props
的history
,因此:
this.props.history.push('/some/path');
它还提供pushState
但已记录的警告已弃用。
如果使用react-router-redux
,它提供了一个push
函数,您可以像这样调度:
import { push } from 'react-router-redux';
this.props.dispatch(push('/some/path'));
但是,这只能用于更改URL,而不能实际导航到页面。
#4楼
这是在ES6上使用react-router v2.0.0
v2.0.0的方法 。 react-router
已从mixins移开。
import React from 'react';
export default class MyComponent extends React.Component {
navigateToPage = () => {
this.context.router.push('/my-route')
};
render() {
return (
<button onClick={this.navigateToPage}>Go!</button>
);
}
}
MyComponent.contextTypes = {
router: React.PropTypes.object.isRequired
}
#5楼
对于这一点,谁不控制服务器端,因此使用哈希路由器v2:
将您的历史记录放入单独的文件中(例如,app_history.js ES6):
import { useRouterHistory } from 'react-router'
import { createHashHistory } from 'history'
const appHistory = useRouterHistory(createHashHistory)({ queryKey: false });
export default appHistory;
并在任何地方使用它!
您的react-router(app.js ES6)入口点:
import React from 'react'
import { render } from 'react-dom'
import { Router, Route, Redirect } from 'react-router'
import appHistory from './app_history'
...
const render((
<Router history={appHistory}>
...
</Router>
), document.querySelector('[data-role="app"]'));
您在任何组件(ES6)中的导航:
import appHistory from '../app_history'
...
ajaxLogin('/login', (err, data) => {
if (err) {
console.error(err); // login failed
} else {
// logged in
appHistory.replace('/dashboard'); // or .push() if you don't need .replace()
}
})
#6楼
对于ES6 + React组件,以下解决方案适用于我。
我关注了Felippe skinner,但添加了端到端解决方案来帮助像我这样的初学者。
以下是我使用的版本:
“反应路由器”:“ ^ 2.7.0”
“反应”:“ ^ 15.3.1”
以下是我的react组件,在其中我使用了react-router进行程序导航:
import React from 'react';
class loginComp extends React.Component {
constructor( context) {
super(context);
this.state = {
uname: '',
pwd: ''
};
}
redirectToMainPage(){
this.context.router.replace('/home');
}
render(){
return <div>
// skipping html code
<button onClick={this.redirectToMainPage.bind(this)}>Redirect</button>
</div>;
}
};
loginComp.contextTypes = {
router: React.PropTypes.object.isRequired
}
module.exports = loginComp;
以下是我的路由器的配置:
import { Router, Route, IndexRedirect, browserHistory } from 'react-router'
render(<Router history={browserHistory}>
<Route path='/' component={ParentComp}>
<IndexRedirect to = "/login"/>
<Route path='/login' component={LoginComp}/>
<Route path='/home' component={HomeComp}/>
<Route path='/repair' component={RepairJobComp} />
<Route path='/service' component={ServiceJobComp} />
</Route>
</Router>, document.getElementById('root'));
#7楼
随着即将推出React-Router v4,现在有了一种新的方法。
import { MemoryRouter, BrowserRouter } from 'react-router';
const navigator = global && global.navigator && global.navigator.userAgent;
const hasWindow = typeof window !== 'undefined';
const isBrowser = typeof navigator !== 'undefined' && navigator.indexOf('Node.js') === -1;
const Router = isBrowser ? BrowserRouter : MemoryRouter;
<Router location="/page-to-go-to"/>
react-lego是一个示例应用程序,显示了如何使用/更新react-router ,并且包括导航该应用程序的示例功能测试。
#8楼
可能不是最好的方法,但是...使用react-router v4,以下Typescript可能会给您一些帮助。
在下面的呈现组件中,例如LoginPage
,可以访问router
对象,只需调用router.transitionTo('/homepage')
进行导航。
导航代码来自 。
"react-router": "^4.0.0-2",
"react": "^15.3.1",
import Router from 'react-router/BrowserRouter'; import { History } from 'react-history/BrowserHistory'; import createHistory from 'history/createBrowserHistory'; const history = createHistory(); interface MatchWithPropsInterface { component: typeof React.Component, router: Router, history: History, exactly?: any, pattern: string } class MatchWithProps extends React.Component<MatchWithPropsInterface,any> { render() { return( <Match {...this.props} render={(matchProps) => ( React.createElement(this.props.component, this.props) )} /> ) } } ReactDOM.render( <Router> {({ router }) => ( <div> <MatchWithProps exactly pattern="/" component={LoginPage} router={router} history={history} /> <MatchWithProps pattern="/login" component={LoginPage} router={router} history={history} /> <MatchWithProps pattern="/homepage" component={HomePage} router={router} history={history} /> <Miss component={NotFoundView} /> </div> )} </Router>, document.getElementById('app') );
#9楼
在当前的React版本(15.3)中, this.props.history.push('/location');
为我工作,但显示以下警告:
browser.js:49警告:[react-router]
props.history
和context.history
已弃用。 请使用context.router
。
我使用context.router
这样解决了它:
import React from 'react';
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.backPressed = this.backPressed.bind(this);
}
backPressed() {
this.context.router.push('/back-location');
}
...
}
MyComponent.contextTypes = {
router: React.PropTypes.object.isRequired
};
export default MyComponent;
#10楼
React-Router V4
如果您使用的是版本4,则可以使用我的库(Shameless插件),您可以在其中简单地调度一个动作,并且一切正常!
dispatch(navigateTo("/aboutUs"));
#11楼
在正常工作之前,我尝试了至少10种方法!
@Felipe Skinner的withRouter
答案对我来说有点不知所措,而且我不确定是否要创建新的“ ExportedWithRouter”类名称。
大约是当前的React-Router 3.0.0和ES6,这是最简单,最干净的方法:
使用ES6的React-Router 3.xx:
import { withRouter } from 'react-router';
class Example extends React.Component {
// use `this.props.router.push('/some/path')` here
};
// Export the decorated class
export default withRouter(Example);
或者,如果不是您的默认班级,则按以下方式导出:
withRouter(Example);
export { Example };
请注意,在3.xx中, <Link>
组件本身正在使用router.push
,因此您可以将传递<Link to=
标记的任何内容传递给它,例如:
this.props.router.push({pathname: '/some/path', query: {key1: 'val1', key2: 'val2'})'
#12楼
根据先前的答案
来自JoséAntonio Postigo和Ben Wheeler
新奇? 用打字稿写
和装饰器的使用
或静态属性/字段
import * as React from "react";
import Component = React.Component;
import { withRouter } from "react-router";
export interface INavigatorProps {
router?: ReactRouter.History.History;
}
/**
* Note: goes great with mobx
* @inject("something") @withRouter @observer
*/
@withRouter
export class Navigator extends Component<INavigatorProps, {}>{
navigate: (to: string) => void;
constructor(props: INavigatorProps) {
super(props);
let self = this;
this.navigate = (to) => self.props.router.push(to);
}
render() {
return (
<ul>
<li onClick={() => this.navigate("/home")}>
Home
</li>
<li onClick={() => this.navigate("/about")}>
About
</li>
</ul>
)
}
}
/**
* Non decorated
*/
export class Navigator2 extends Component<INavigatorProps, {}> {
static contextTypes = {
router: React.PropTypes.object.isRequired,
};
navigate: (to: string) => void;
constructor(props: INavigatorProps, context: any) {
super(props, context);
let s = this;
this.navigate = (to) =>
s.context.router.push(to);
}
render() {
return (
<ul>
<li onClick={() => this.navigate("/home")}>
Home
</li>
<li onClick={() => this.navigate("/about")}>
About
</li>
</ul>
)
}
}
无论今天安装了什么npm。 “ react-router”:“ ^ 3.0.0”和
“ @ types / react-router”:“ ^ 2.0.41”
#13楼
带有钩子的React Router v5.1.0
如果您使用React> 16.8.0和功能组件,则在React Router> 5.1.0中有一个新的useHistory
挂钩。
import { useHistory } from "react-router-dom";
function HomeButton() {
let history = useHistory();
function handleClick() {
history.push("/home");
}
return (
<button type="button" onClick={handleClick}>
Go home
</button>
);
}
反应路由器v4
使用React Router v4,您可以采用三种方法在组件内进行编程路由。
- 使用
withRouter
高阶组件。 - 使用合成并渲染
<Route>
- 使用
context
。
React Router主要是history
库的包装器。 history
处理与浏览器window.history
。交互的history
,以及浏览器和哈希历史记录。 它还提供了内存历史记录,这对于没有全局历史记录的环境很有用。 这在使用Node进行移动应用程序开发( react-native
)和单元测试中特别有用。
history
实例有两种导航方法: push
和replace
。 如果您将history
视为访问过的位置数组,则push
将向该位置添加新位置,而replace
将用新位置replace
该数组中的当前位置。 通常,您在导航时会希望使用push
方法。
在早期版本的React Router中,您必须创建自己的history
实例,但是在v4中, <BrowserRouter>
, <HashRouter>
和<MemoryRouter>
组件将为您创建浏览器,哈希和内存实例。 React Router通过router
对象下的上下文使与路由器关联的history
实例的属性和方法可用。
1.使用withRouter
高阶组件
withRouter
高阶组件将注入history
对象作为该组件的支持。 这使您无需处理context
即可访问push
和replace
方法。
import { withRouter } from 'react-router-dom'
// this also works with react-router-native
const Button = withRouter(({ history }) => (
<button
type='button'
onClick={() => { history.push('/new-location') }}
>
Click Me!
</button>
))
2.使用合成并渲染<Route>
<Route>
组件不仅用于匹配位置。 您可以渲染无路径的路线, 它将始终与当前位置匹配 。 <Route>
组件传递与withRouter
相同的道具,因此您将能够通过history
道具访问history
方法。
import { Route } from 'react-router-dom'
const Button = () => (
<Route render={({ history}) => (
<button
type='button'
onClick={() => { history.push('/new-location') }}
>
Click Me!
</button>
)} />
)
3.使用上下文*
但是你可能不应该
最后一个选项是只有在您熟悉使用React的上下文模型时才应使用的选项。 尽管上下文是一个选项,但应该强调的是上下文是不稳定的API,React在其文档中有“ 为什么不使用上下文”一节。 因此,使用后果自负!
const Button = (props, context) => (
<button
type='button'
onClick={() => {
// context.history.push === history.push
context.history.push('/new-location')
}}
>
Click Me!
</button>
)
// you need to specify the context type so that it
// is available within the component
Button.contextTypes = {
history: React.PropTypes.shape({
push: React.PropTypes.func.isRequired
})
}
1和2是最简单的实现方式,因此对于大多数用例来说,它们是最好的选择。
此外,您可以从以下链接中获得有关路由,URL参数和嵌套路由的更多知识。
在React JS中路由
-逐步说明如何在ReactJS中集成react-router
使用React Router的URL参数
-在这里您可以了解如何使用React Router设置URL参数。 URL参数路由的主要用途是根据其动态URL呈现相同的组件。
React JS中的嵌套路由
-如果要在主路径中加载子路径,则必须创建嵌套路径。 这是它的现场示例。
希望能帮到你!
#14楼
要以编程方式进行导航,您需要将新的历史记录推送到 component
的props.history ,这样可以为您完成工作:
//using ES6
import React from 'react';
class App extends React.Component {
constructor(props) {
super(props)
this.handleClick = this.handleClick.bind(this)
}
handleClick(e) {
e.preventDefault()
/* Look at here, you can add it here */
this.props.history.push('/redirected');
}
render() {
return (
<div>
<button onClick={this.handleClick}>
Redirect!!!
</button>
</div>
)
}
}
export default App;
#15楼
React-Router 4.x回答:
最后,我希望有一个历史对象,甚至可以携带外部组件。 我想做的是拥有一个按需导入的history.js文件,并对其进行操作。
您只需要将BrowserRouter
更改为Router,然后指定历史记录BrowserRouter
即可。 除了拥有自己的历史对象可以随意操作之外,这对您没有任何改变。
您需要安装历史记录 , react-router
使用的库。
用法示例,ES6表示法:
history.js
import createBrowserHistory from 'history/createBrowserHistory'
export default createBrowserHistory()
BasicComponent.js
import React, { Component } from 'react';
import history from './history';
class BasicComponent extends Component {
goToIndex(e){
e.preventDefault();
history.push('/');
}
render(){
return <a href="#" onClick={this.goToIndex}>Previous</a>;
}
}
编辑2018年4月16日:
如果必须从实际从Route
组件渲染的组件中导航,则还可以从props访问历史记录,如下所示:
BasicComponent.js
import React, { Component } from 'react';
class BasicComponent extends Component {
navigate(e){
e.preventDefault();
this.props.history.push('/url');
}
render(){
return <a href="#" onClick={this.navigate}>Previous</a>;
}
}
#16楼
如果您使用哈希或浏览器历史记录,则可以
hashHistory.push('/login');
browserHistory.push('/login');
#17楼
在React-Router v4和ES6中
您可以使用withRouter
和this.props.history.push
。
import {withRouter} from 'react-router-dom';
class Home extends Component {
componentDidMount() {
this.props.history.push('/redirect-to');
}
}
export default withRouter(Home);
#18楼
只需使用this.props.history.push('/where/to/go');
#19楼
反应路由器V4
tl:dr;
if (navigate) {
return <Redirect to="/" push={true} />
}
简单且声明性的答案是,您需要将<Redirect to={URL} push={boolean} />
与setState()
结合使用
push:布尔值-设置为 true时,重定向会将新条目推入历史记录,而不是替换当前条目。
import { Redirect } from 'react-router'
class FooBar extends React.Component {
state = {
navigate: false
}
render() {
const { navigate } = this.state
// here is the important part
if (navigate) {
return <Redirect to="/" push={true} />
}
// ^^^^^^^^^^^^^^^^^^^^^^^
return (
<div>
<button onClick={() => this.setState({ navigate: true })}>
Home
</button>
</div>
)
}
}
PS。 该示例使用ES7 +属性初始化程序来初始化状态。 如果您有兴趣,也请在这里查看。
#20楼
也许不是最好的解决方案,但可以完成工作:
import { Link } from 'react-router-dom';
// create functional component Post
export default Post = () => (
<div className="component post">
<button className="button delete-post" onClick={() => {
// ... delete post
// then redirect, without page reload, by triggering a hidden Link
document.querySelector('.trigger.go-home').click();
}}>Delete Post</button>
<Link to="/" className="trigger go-home hidden"></Link>
</div>
);
基本上,与一个动作(在这种情况下为后删除)相关的逻辑最终将调用重定向触发器。 这不是理想的,因为您将在标记中添加DOM节点“触发”,以便您在需要时可以方便地调用它。 另外,您将直接与DOM交互,而在React组件中可能不需要DOM。
不过,这种重定向并不是经常需要的。 因此,组件标记中的一个或两个额外的隐藏链接不会对您造成太大的伤害,特别是如果给它们提供有意义的名称。
#21楼
正确的答案是在撰写本文时适合我的
this.context.router.history.push('/');
但是您需要将PropTypes添加到您的组件中
Header.contextTypes = {
router: PropTypes.object.isRequired
}
export default Header;
不要忘记导入PropTypes
import PropTypes from 'prop-types';
#22楼
如果发生配对RR4 W /通过Redux的反应,路由器终极版 ,使用路由动作的创造者,从react-router-redux
是一个选项,以及。
import { push, replace, ... } from 'react-router-redux'
class WrappedComponent extends React.Component {
handleRedirect(url, replaceState = true) {
replaceState
? this.props.dispatch(replace(url))
: this.props.dispatch(push(url))
}
render() { ... }
}
export default connect(null)(WrappedComponent)
如果使用redux thunk / saga管理异步流,请在redux操作中导入上述操作创建者,并使用mapDispatchToProps挂钩以响应组件,可能会更好。
#23楼
要将withRouter
与基于类的组件一起使用,请尝试以下类似方法。 别忘了更改export语句以与withRouter
一起使用:
import { withRouter } from 'react-router-dom'
class YourClass extends React.Component {
yourFunction = () => {
doSomeAsyncAction(() =>
this.props.history.push('/other_location')
)
}
render() {
return (
<div>
<Form onSubmit={ this.yourFunction } />
</div>
)
}
}
export default withRouter(YourClass);
#24楼
在React Router v4中。 我遵循两种方式以编程方式进行路由。
1. this.props.history.push("/something/something")
2. this.props.history.replace("/something/something")
第二
替换历史记录堆栈上的当前条目
要获取道具的历史记录,您可能需要使用
#25楼
那些在react-router v4上实现此问题的人。
这是一个用于从redux动作浏览react应用程序的可行解决方案。
history.js
import createHistory from 'history/createBrowserHistory'
export default createHistory()
App.js / Route.jsx
import { Router, Route } from 'react-router-dom'
import history from './history'
...
<Router history={history}>
<Route path="/test" component={Test}/>
</Router>
another_file.js或redux文件
import history from './history'
history.push('/test') // this should change the url and re-render Test component
感谢此评论: ReactTraining问题评论
#26楼
简单的反应路由:
链接到我的代码沙箱。 它还有其他一些简单的react-redux程序。
#27楼
对于React Router v4 +
假设您不需要在初始渲染过程中进行导航(可以使用<Redirect>
组件),这就是我们在应用程序中所做的。
定义一个返回null的空路由,这将使您能够访问历史对象。 您需要在定义Router
的顶层执行此操作。
现在,您可以执行历史上可以完成的所有操作,例如history.push()
, history.replace()
, history.go(-1)
等!
import React from 'react';
import { HashRouter, Route } from 'react-router-dom';
let routeHistory = null;
export function navigateTo(path) {
if(routeHistory !== null) {
routeHistory.push(path);
}
}
export default function App(props) {
return (
<HashRouter hashType="noslash">
<Route
render={({ history }) => {
routeHistory = history;
return null;
}}
/>
{/* Rest of the App */}
</HashRouter>
);
}
#28楼
这对我有用,不需要特殊的进口:
<input
type="button"
name="back"
id="back"
class="btn btn-primary"
value="Back"
onClick={() => { this.props.history.goBack() }}
/>
#29楼
您还可以在无状态组件中使用useHistory
挂钩。 文档中的示例。
import { useHistory } from "react-router"
function HomeButton() {
const history = useHistory()
return (
<button type="button" onClick={() => history.push("/home")}>
Go home
</button>
)
}
注意:钩子已添加到
react-router@5.1.0
并且需要react@>=16.8
#30楼
因此,在我的回答中,有3种不同的方式可以以编程方式重定向到路线。 已经介绍了一些解决方案,但以下解决方案仅针对带有附加演示应用程序的功能组件 。
使用以下版本:
反应: 16.12.0
react-dom: 16.12.0
反应路由器: 5.1.2
react-router-dom: 5.1.2
打字稿: 3.7.2
组态:
因此,首先解决方案是使用HashRouter
,其配置如下:
<HashRouter>
// ... buttons for redirect
<Switch>
<Route exact path="/(|home)" children={Home} />
<Route exact path="/usehistory" children={UseHistoryResult} />
<Route exact path="/withrouter" children={WithRouterResult} />
<Route exact path="/redirectpush" children={RedirectPushResult} />
<Route children={Home} />
</Switch>
</HashRouter>
从有关<HashRouter>
的文档中 :
<Router>
使用URL的哈希部分(即window.location.hash
)使您的UI与URL保持同步。
解决方案:
- 使用
<Redirect>
推送使用useState
:
在功能组件(我的存储库中的RedirectPushAction
组件)中使用,我们可以使用useState
来处理重定向。 棘手的部分是,一旦发生重定向,我们需要将redirect
状态设置回false
。 通过将setTimeOut
为0
延迟,我们等待,直到React将Redirect
提交到DOM,然后取回该按钮以便下次使用。
请在下面找到我的示例:
const [redirect, setRedirect] = useState(false);
const handleRedirect = useCallback(() => {
let render = null;
if (redirect) {
render = <Redirect to="/redirectpush" push={true} />
// in order wait until commiting to the DOM
// and get back the button for clicking next time
setTimeout(() => setRedirect(false), 0);
}
return render;
}, [redirect]);
return <>
{handleRedirect()}
<button onClick={() => setRedirect(true)}>
Redirect push
</button>
</>
从<Redirect>
文档中:
渲染
<Redirect>
将导航到新位置。 新位置将覆盖历史记录堆栈中的当前位置,就像服务器端重定向(HTTP 3xx)一样。
- 使用
useHistory
钩子:
在我的解决方案中,有一个名为UseHistoryAction
的组件,它表示以下内容:
let history = useHistory();
return <button onClick={() => { history.push('/usehistory') }}>
useHistory redirect
</button>
useHistory
挂钩使我们可以访问历史记录对象,这有助于我们以编程方式导航或更改路线。
- 使用
withRouter
,从props
获取history
:
创建了一个名为WithRouterAction
组件,显示如下:
const WithRouterAction = (props:any) => {
const { history } = props;
return <button onClick={() => { history.push('/withrouter') }}>
withRouter redirect
</button>
}
export default withRouter(WithRouterAction);
从withRouter
文档中阅读:
您可以通过
withRouter
高阶组件访问history
对象的属性和最接近的<Route>
匹配项。 每当呈现时,withRouter
都会将更新的match
,location
和history
道具传递给包装的组件。
演示:
为了更好地表示,我用这些示例构建了一个GitHub存储库,请在下面找到它:
https://github.com/norbitrial/react-router-programmatically-redirect-examples
我希望这有帮助!