使用React路由器编程导航

使用react-router,我可以使用Link元素来创建由React路由器本地处理的链接。

我在内部看到它调用this.context.transitionTo(...)

我想做一个导航。不是从链接,而是从下拉选择(作为示例)。我如何在代码中做到这一点?什么是this.context

我看到了Navigation混合,但是我可以在没有mixins的情况下做到这一点吗?

1394708 次浏览

React路由器v6+答案

太长别读:您可以使用新的useNavigate钩子。

import { useNavigate } from "react-router-dom";
function Component() {let navigate = useNavigate();// Somewhere in your code, e.g. inside a handler:navigate("/posts");}

useNavigate钩子返回一个可用于编程导航的函数。

来自反应路由器文件的示例

import { useNavigate } from "react-router-dom";
function SignupForm() {let navigate = useNavigate();
async function handleSubmit(event) {event.preventDefault();await submitForm(event.target);navigate("../success", { replace: true });// replace: true will replace the current entry in// the history stack instead of adding a new one.
}
return <form onSubmit={handleSubmit}>{/* ... */}</form>;}

React-Rout5.1.0+答案(使用钩子和React>16.8)

您可以使用useHistory挂钩函数组件和编程导航:

import { useHistory } from "react-router-dom";
function HomeButton() {let history = useHistory();// use history.push('/some/path') here};

React-路由器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}/>在您的组件中具有this.props.history

React-路由器3.0.0+答案

在3.0及更高版本中,将路由器用作组件的道具。

class Example extends React.Component {// use `this.props.router.push('/some/path')` here};

React-路由器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 classvar DecoratedExample = withRouter(Example);
// PropTypesExample.propTypes = {router: React.PropTypes.shape({push: React.PropTypes.func.isRequired}).isRequired};

React-路由器2.0.0+答案

此版本向后兼容1. x,因此无需升级指南。只需浏览示例就足够了。

也就是说,如果您希望切换到新模式,路由器内部有一个browserHistory模块,您可以使用它进行访问

import { browserHistory } from 'react-router'

现在您可以访问浏览器历史记录,因此您可以执行推送、替换等操作……例如:

browserHistory.push('/some/path')

进一步阅读:历史导航


React-Rout1. x. x答案

我不会详细介绍升级细节。您可以在升级指南中阅读有关内容

这里问题的主要变化是从Navigation混合到History。现在它使用浏览器历史API来更改路由,所以从现在开始我们将使用pushState()

下面是一个使用Mixin的例子:

var Example = React.createClass({mixins: [ History ],navigateToHelpPage () {this.history.pushState(null, `/help`);}})

请注意,这个History来自机架/历史项目。不是来自React-路由器本身。

如果您出于某种原因(可能是因为ES6类)不想使用Misin,那么您可以从this.props.history访问从路由器获得的历史记录。它将仅适用于您的Router呈现的组件。因此,如果您想在任何子组件中使用它,它需要通过props作为属性传递。

您可以在他们的1.0. x留档中阅读有关新版本的更多信息

这里是一个专门关于在组件之外导航的帮助页面

它建议抓取引用history = createHistory()并调用replaceState

React-路由器0.13. x答案

我遇到了同样的问题,只能用react-router附带的导航混音找到解决方案。

我是这样做的

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>);}});

我能够调用transitionTo()而无需访问.context

或者你可以试试花哨的ES6class

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-Rout-Redux开发完成

备注:如果您使用的是Redux,还有一个名为React-Rout-Redux开发完成给你React路由器的Redux绑定,使用与React-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

<buttondisabled={submitting}className="cancel_button"onClick={(e) => {e.preventDefault()this.props.onBackPress()}}>CANCEL</button>

警告:此答案仅涵盖1.0之前的ReactRout版本

之后我会用1.0.0-rc1用例更新这个答案!

你也可以在没有混合的情况下做到这一点。

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,否则它是不可访问的。

至于什么是上下文,它是一个对象,就像props一样,从父级传递给子级,但它是隐式传递的,每次都不必重新声明props。见https://www.tildedave.com/2014/11/15/introduction-to-contexts-in-react-js.html

React-Rout v2开发环境

对于最近的版本(v2.0.0-rc5),推荐的导航方法是直接推送到历史单例。您可以在在组件文档之外导航中看到它的作用。

相关摘录:

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,而不是实际导航到页面。

这是你如何用#0ES6来做这件事。react-router已经远离了混合。

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}

对于这个,谁不控制服务器端,因此使用哈希路由器v2:

历史放入单独的文件(例如app_history.jsES6):

import { useRouterHistory } from 'react-router'import { createHashHistory } from 'history'const appHistory = useRouterHistory(createHashHistory)({ queryKey: false });
export default appHistory;

并在任何地方使用它!

反应路由器(app.jsES6)的切入点:

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 inappHistory.replace('/dashboard'); // or .push() if you don't need .replace()}})

对于ES6+React组件,以下解决方案适合我。

我跟随了Felippe斯金纳,但添加了一个端到端的解决方案来帮助像我这样的初学者。

以下是我使用的版本:

取值范围取值范围取值范围"react-router":"2.7.0"

请求示例:响应示例:"React":"^15.3.1"

下面是我的反应组件,我使用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'));

随着React-路由器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-router的示例应用程序,它包括导航应用程序的示例功能测试。

这可能不是最好的方法,但是……使用react-router v4,下面的TypeScript代码可以为一些人提供一个想法。

在下面的渲染组件中,例如LoginPagerouter对象是可访问的,只需调用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'));

在当前的React版本(15.3)中,this.props.history.push('/location');对我有用,但它显示了以下警告:

browser.js:49警告:[react-router]props.historycontext.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;

React-Rout V4开发环境

如果您使用的是版本4,那么您可以使用我的库(无耻插件),您只需调度一个操作,一切都正常工作!

dispatch(navigateTo("/aboutUs"));

trippler

这是最简单、最干净的方法,大约是当前的React-Rout 3.0.0和ES6

带有ES6的React-路由器3. x. x:

import { withRouter } from 'react-router';
class Example extends React.Component {// use `this.props.router.push('/some/path')` here};
// Export the decorated classexport default withRouter(Example);

或者,如果它不是您的默认类,则导出如下:

withRouter(Example);export { Example };

请注意,在3. x. x中,<Link>组件本身使用router.push,因此您可以向其传递任何要传递<Link to=标记的内容,例如:

   this.props.router.push({pathname: '/some/path', query: {key1: 'val1', key2: 'val2'})'

基于之前的来自JoséAntonio Postigo的回复和本·惠勒

新颖性?是用TypeScript编写并使用装饰器静态属性/字段

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*/@withRouterexport 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"和

响应路由器

响应路由器

带有钩子的React路由器v5.1.0

如果您使用的是React>16.8.0和功能组件,React路由器>5.1.0中有一个新的useHistory挂钩。

import { useHistory } from "react-router-dom";
function HomeButton() {const history = useHistory();
function handleClick() {history.push("/home");}
return (<button type="button" onClick={handleClick}>Go home</button>);}

React路由器v4

使用React路由器的v4,您可以采用三种方法在组件内进行编程路由。

  1. 使用withRouter高阶组件。
  2. 使用合成并渲染<Route>
  3. 使用context

React路由器主要是#0库的包装器。history通过浏览器和哈希历史记录为您处理与浏览器#2的交互。它还提供了一个内存历史记录,对于没有全局历史记录的环境很有用。这在移动应用程序开发(react-native)和Node的单元测试中特别有用。

history实例有两种导航方法:pushreplace。如果您将history视为访问位置的数组,push将向数组中添加一个新位置,replace将用新位置替换数组中的当前位置。通常,您在导航时会希望使用push方法。

在早期版本的React路由器中,您必须创建自己的history实例,但在v4中,<BrowserRouter><HashRouter><MemoryRouter>组件将为您创建浏览器、哈希和内存实例。React路由器通过router对象下的上下文提供与路由器关联的history实例的属性和方法。

1.使用withRouter高阶组件

withRouter高阶组件将注入history对象作为组件的道具。这允许您访问pushreplace方法,而无需处理context

import { withRouter } from 'react-router-dom'// this also works with react-router-native
const Button = withRouter(({ history }) => (<buttontype='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}) => (<buttontype='button'onClick={() => { history.push('/new-location') }}>Click Me!</button>)} />)

3.使用上下文*

但你也许不该

最后一个选项是只有在您对使用React的背景模型感到满意时才应该使用的选项(React的Context API从v16开始是稳定的)。

const Button = (props, context) => (<buttontype='button'onClick={() => {// context.history.push === history.pushcontext.history.push('/new-location')}}>Click Me!</button>)
// you need to specify the context type so that it// is available within the componentButton.contextTypes = {history: React.PropTypes.shape({push: React.PropTypes.func.isRequired})}

1和2是最简单的实现选择,因此对于大多数用例来说,它们是您最好的选择。

要以编程方式进行导航,您需要将新的历史推送到component中的props.history,因此这样的东西可以为您完成工作:

//using ES6import 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;

React-路由器4. x答案

就我而言,我喜欢有一个单一的历史对象,我甚至可以携带外部组件。我喜欢有一个我按需导入的history.js文件,然后只需操作它。

您只需将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>;}}

如果您必须从实际从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>;}}

如果您使用哈希或浏览器历史记录,那么您可以

hashHistory.push('/login');browserHistory.push('/login');

React-Rout v4开发环境ES6

您可以使用withRouterthis.props.history.push

import {withRouter} from 'react-router-dom';
class Home extends Component {
componentDidMount() {this.props.history.push('/redirect-to');}}
export default withRouter(Home);

只需使用this.props.history.push('/where/to/go');

React路由器v6

我有一段时间没有接触React了,但要感谢并强调下面的评论由Shimrit Snapir

on React-Router 6.0 <Redirect /> changed to <Navigate />

React路由器V4

tl:博士;

if (navigate) {return <Redirect to="/" push={true} />}

简单而声明性的答案是,您需要将<Redirect to={URL} push={boolean} />setState()结合使用

推: boolean-如果为true,重定向将把新条目推送到历史记录中,而不是替换当前条目。


import { Redirect } from 'react-router'
class FooBar extends React.Component {state = {navigate: false}
render() {const { navigate } = this.state
// Here is the important partif (navigate) {return <Redirect to="/" push={true} />}// ^^^^^^^^^^^^^^^^^^^^^^^
return (<div><button onClick={() => this.setState({ navigate: true })}>Home</button></div>)}}

一个完整的例子是这里。阅读更多这里

PS。该示例使用ES7+属性初始化器来初始化状态。如果你感兴趣,也可以在这里查看

也许不是最好的解决方案,但它完成了工作:

import { Link } from 'react-router-dom';
// Create functional component Postexport default Post = () => (<div className="component post">
<button className="button delete-post" onClick={() => {// ... delete post// then redirect, without page reload, by triggering a hidden Linkdocument.querySelector('.trigger.go-home').click();}}>Delete Post</button>
<Link to="/" className="trigger go-home hidden"></Link>
</div>);

基本上,与一个操作(在这种情况下是删除后)绑定的逻辑最终将调用触发器进行重定向。这并不理想,因为你将向标记添加DOM节点“触发器”,以便在需要时方便地调用它。此外,你将直接与DOM交互,这在React组件中可能不需要。

尽管如此,这种类型的重定向并不经常需要。因此,在您的组件标记中添加一两个额外的隐藏链接不会造成太大伤害,特别是如果您给它们起了有意义的名称。

正确的答案是在我写作的时候

this.context.router.history.push('/');

但是您需要将PropTypes添加到您的组件中

Header.contextTypes = {router: PropTypes.object.isRequired}export default Header;

不要忘记导入PropTypes

import PropTypes from 'prop-types';

如果您碰巧通过反应路由器将RR4与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挂钩到React组件可能会更好。

要将withRouter与基于类的组件一起使用,请尝试以下操作。不要忘记将导出语句更改为使用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);

在React路由器v4中,我遵循这两种方式以编程方式路由。

  1. this.props.history.push("/something/something")
  2. this.props.history.replace("/something/something")

第二名

替换历史堆栈上的当前条目

要在道具中获取历史记录,您可能需要包装您的组件

在React路由器v6中

import { useNavigate } from "react-router-dom";
function Invoices() {let navigate = useNavigate();return (<div><NewInvoiceFormonSubmit={async event => {let newInvoice = await createInvoice(event.target);navigate(`/invoices/${newInvoice.id}`);}}/></div>);}

开始使用React路由器v6

那些在React路由器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还原文件

import history from './history'
history.push('/test') // This should change the URL and rerender Test component

感谢GitHub上的评论:React训练问题评论

对于React路由器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"><Routerender={({ history }) => {routeHistory = history;return null;}}/>{/* Rest of the App */}</HashRouter>);}

这对我很有效,不需要特殊进口:

<inputtype="button"name="back"id="back"class="btn btn-primary"value="Back"onClick={() => { this.props.history.goBack() }}/>

您还可以在无状态组件中使用#0钩子。留档中的示例:

import { useHistory } from "react-router"
function HomeButton() {const history = useHistory()
return (<button type="button" onClick={() => history.push("/home")}>Go home</button>)}

注意:钩子在#0中添加并需要react@>=16.8

在我的回答中,有三种不同的方法可以以编程方式重定向到路由。已经介绍了一些解决方案,但以下解决方案仅针对功能组件和一个额外的演示应用程序。

使用以下版本:

回复:16.13.1

React-dom:16.13.1//用户注册账号

React路由器:5.2.0

react-router-dom:5.2.0//路由器类型

打字稿: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同步。

解决方案:

  1. 使用<Redirect>推送使用useState

在功能组件中使用(我的存储库中的#0组件),我们可以使用#1来处理重定向。棘手的部分是一旦重定向发生,我们需要将redirect状态设置回false。通过使用setTimeOut0延迟,我们等待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 committing to the DOM// and get back the button for clicking next timesetTimeout(() => setRedirect(false), 0);}return render;}, [redirect]);
return <>{handleRedirect()}<button onClick={() => setRedirect(true)}>Redirect push</button></>

#0留档:

渲染<Redirect>将导航到一个新位置。新位置将覆盖历史堆栈中的当前位置,就像服务器端重定向(HTTP 3xx)一样。

  1. 使用useHistory钩子:

在我的解决方案中,有一个名为#0的组件,它代表以下内容:

let history = useHistory();
return <button onClick={() => { history.push('/usehistory') }}>useHistory redirect</button>

useHistory钩子允许我们访问历史对象,这有助于我们以编程方式导航或更改路由。

  1. 使用withRouter,从props获取history

创建了一个名为#0的组件,显示如下:

const WithRouterAction = (props:any) => {const { history } = props;
return <button onClick={() => { history.push('/withrouter') }}>withRouter redirect</button>}
export default withRouter(WithRouterAction);

#0留档:

您可以通过withRouter高阶组件访问history对象的属性和最接近的<Route>匹配。withRouter将在渲染时将更新的matchlocationhistory道具传递给包装组件。

演示:

为了更好地表示,我使用这些示例构建了一个GitHub存储库,请在下面找到它:

React路由器编程重定向示例

react-router-dom:5.1.2

  • 该网站有3个页面,所有页面都在浏览器中动态呈现。

  • 虽然页面永远不会刷新,但请注意React路由器如何在您浏览网站时保持URL最新。这保留浏览器历史记录,确保后面的内容按钮和书签正常工作

  • ASwitch遍历它所有的子节点元素并渲染第一个其路径匹配当前URL。随时使用你有多条路线,但你只想要一条#36825;的时间

import React from "react";import {BrowserRouter as Router,Switch,Route,Link} from "react-router-dom";


export default function BasicExample() {return (<Router><div><ul><li><Link to="/">Home</Link></li><li><Link to="/about">About</Link></li><li><Link to="/dashboard">Dashboard</Link></li></ul>
<hr />
<Switch><Route exact path="/"><Home /></Route><Route path="/about"><About /></Route><Route path="/dashboard"><Dashboard /></Route></Switch></div></Router>);}
// You can think of these components as "pages"// in your app.
function Home() {return (<div><h2>Home</h2></div>);}
function About() {return (<div><h2>About</h2></div>);}
function Dashboard() {return (<div><h2>Dashboard</h2></div>);}```

试试React钩子路由器,“react-router的现代替代品”:

import { useRoutes, usePath, A} from "hookrouter";

要回答OP关于通过选择框链接的问题,您可以这样做:

navigate('/about');

更新答案

我认为React Hook路由器是一个很好的入门工具包,帮助我学习路由,但我已经更新到反应路由器,因为它的历史和查询参数处理。

import { useLocation, useHistory } from 'react-router-dom';

const Component = (props) => {const history = useHistory();
// Programmatically navigatehistory.push(newUrlString);}

你把你想导航到的地方推到location.history.

带钩子的React路由器v6

import {useNavigate} from 'react-router-dom';let navigate = useNavigate();navigate('home');

并在浏览器历史记录中移动,

navigate(-1); ---> Go backnavigate(1);  ---> Go forwardnavigate(-2); ---> Move two steps backward.

以编程方式在基于类的组件中导航。

import { Redirect } from "react-router-dom";
class MyComponent extends React.Component{state = {rpath: null}
const goTo = (path) => this.setState({rpath: path});
render(){if(this.state.rpath){return <Redirect to={this.state.rpath}/>}..........}}

如果您使用的是较新版本的React,则使用“useHistory”挂钩是最佳选择。

这已经提到过,我们可以在最后一次更新React路由器V6(不包括useHistory)中使用useNavigate()进行导航

import { useNavigate } from 'react-router-dom';
const myComponent = () => {const navigate = useNavigate();navigate('my_url');...}

但是我在这里找不到的是调用导航出React组件,就像在redux-saga函数中导航页面到另一个页面一样。以防万一,如果你有同样的问题,这是我找到的。

在你的根组件中(我称之为<App />

import { useNavigate } from 'react-router-dom';import useBus from 'use-bus';
const App = () => {const navigate = useNavigate();useBus('@@ui/navigate', (action) => navigate(action.payload.url), []);...}

超出React组件(在我的情况下redux-saga函数)

import { dispatch } from 'use-bus';
dispatch({ type: '@@ui/navigate', payload: { url: '/404' } });

希望有帮助!

对于那些已经在使用React路由器v6的人来说,这可以使用react-router提供的useNavigate挂钩来完成。

使用这个钩子导航非常简单:

import { generatePath, useNavigate } from 'react-router';
navigate(-1); // navigates backnavigate('/my/path'); // navigates to a specific pathnavigate(generatePath('my/path/:id', { id: 1 })); // navigates to a dynamic path, generatePath is very useful for url replacements

最新react-router-dom v6下载地址

useHistory()被替换为useNavigate()

您需要使用:

import { useNavigate } from 'react-router-dom';const navigate = useNavigate();navigate('/your-page-link');

只需使用useNavigate来简化最新版本的React

<强>Newfile.js

import { useNavigate } from "react-router-dom";
const Newfile = () => {const navigate = useNavigate();   
....
navigate("yourdesiredlocation");
....}
export default Newfile;

在代码中使用上面的useNavigate功能。

只需使用来自React路由器dom的useNavigate

import { useNavigate } from "react-router-dom";
const MYComponent = () => {const navigate = useNavigate();
navigate("Xyz/MYRoutes");
 
}
export default MYComponent;

在代码中使用上面的useNavigate功能。

在React router的上下文中,已经有<强>吨个答案可以正确准确地回答这个问题,但我想花一点时间指出我在其他答案中没有看到的东西。

有点像堆栈溢出的比喻,建议以不同于原始问题的方式做一些事情,然而在这种情况下,由于问题的年龄,我觉得问题在当前时间会有不同的陈述。

我建议放弃react-router,只需通过window.location.href = [your url here]推送到本机浏览器位置,并通过regex(或精确)匹配window.location.pathname与您的预期路径检查路径。

简单的答案通常是最好的答案,在这种情况下,原生位置对象API更好地服务于React路由器的用例。