使用react-router
我可以使用Link
元素创建由反应路由器本地处理的链接。
我在内部看到它调用this.context.transitionTo(...)
。
我想进行导航,但不是从链接中进行导航,例如下拉选项。我怎么能在代码中这样做?什么是this.context
?
我看到了Navigation
mixin,但我可以不用mixin吗?
答案 0 :(得分:941)
React Router v4
使用React Router的v4,您可以采用三种方法在组件内进行编程路由。
withRouter
高阶组件。<Route>
context
。 React Router主要是history
库的包装器。 history
通过浏览器和哈希历史记录处理与浏览器window.history
的交互。它还提供了一个内存历史记录,对于没有全局历史记录的环境非常有用。这在移动应用程序开发(react-native
)和使用Node的单元测试中特别有用。
history
个实例有两种导航方法:push
和replace
。如果您将history
视为一系列已访问过的位置,push
将向阵列添加新位置,replace
将使用新位置替换阵列中的当前位置。通常,您需要在导航时使用push
方法。
在早期版本的React Router中,您必须创建自己的history
实例,但在第4版中,<BrowserRouter>
,<HashRouter>
和<MemoryRouter>
组件将创建一个浏览器,哈希和内存实例。 React Router通过history
对象下的上下文使与您的路由器关联的router
实例的属性和方法可用。
withRouter
高阶组件 withRouter
高阶组件将history
对象作为组件的支柱注入。这样,您就可以访问push
和replace
方法,而无需处理context
。
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>
))
<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>
)} />
)
但你可能不应该
最后一个选项是您只有在使用React的context模型时才能使用的选项。虽然上下文是一种选择,但应该强调上下文是一个不稳定的API,React在其文档中有一个Why Not To Use Context部分。所以使用风险自负!
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是最简单的选择,所以对于大多数用例来说,它们是你最好的选择。
答案 1 :(得分:784)
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
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')
进一步阅读: Histories和 Navigation
React-Router 1.x.x 答案
我不会进入升级细节。您可以在Upgrade Guide
中了解相关信息这里问题的主要变化是从导航mixin到History的变化。现在它使用浏览器历史记录API来更改路线,因此我们将从现在开始使用pushState()
。
这是一个使用Mixin的例子:
var Example = React.createClass({
mixins: [ History ],
navigateToHelpPage () {
this.history.pushState(null, `/help`);
}
})
请注意,此History
来自rackt/history项目。不是来自React-Router本身。
如果您因某些原因不想使用Mixin(可能是因为ES6类),那么您可以从this.props.history
访问路由器获得的历史记录。它只能由路由器呈现的组件访问。因此,如果要在任何子组件中使用它,则需要通过props
作为属性传递它。
这是a help page specifically about navigating outside your component
建议抓取引用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>);
}
});
我无需访问transitionTo()
.context
或者您可以尝试花哨的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
};
<强>阵营-路由器-终极版强>
注意:如果您正在使用Redux,则会有另一个名为的项目 给你的React-Router-Redux ReactRouter的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 强>
<button
disabled={submitting}
className="cancel_button"
onClick={(e) => {
e.preventDefault()
this.props.onBackPress()
}}
>
CANCEL
</button>
答案 2 :(得分:485)
React-Router v2
对于最新版本(v2.0.0-rc5
),推荐的导航方法是直接推送历史单例。您可以在Navigating outside of Components doc中看到这一点。
相关摘录:
import { browserHistory } from 'react-router';
browserHistory.push('/some/path');
如果使用较新的react-router API,则需要在组件内部使用来自history
的{{1}}:
this.props
它还提供this.props.history.push('/some/path');
,但每个已记录的警告都会弃用。
如果使用pushState
,它会提供react-router-redux
功能,您可以这样发送:
push
但是,这可能仅用于更改网址,而不是实际导航到网页。
答案 3 :(得分:46)
以下是使用react-router v2.0.0
ES6执行此操作的方法。 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
}
答案 4 :(得分:32)
React-Router 4.x答案:
在我的结尾,我喜欢有一个历史对象,我可以携带甚至外部组件。我喜欢做的是拥有一个我按需导入的单个history.js文件,并且只是操作它。
您只需将BrowserRouter
更改为路由器,然后指定历史记录道具。除了您拥有自己可以根据需要操作的历史对象外,这对您没有任何改变。
您需要安装react-router
import createBrowserHistory from 'history/createBrowserHistory'
export default createBrowserHistory()
使用的库。
示例用法,ES6表示法:
<强> history.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>;
}
}
<强> BasicComponent.js 强>
Route
编辑2018年4月16日:
如果您必须从实际从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>;
}
}
组件呈现的组件导航,您还可以从道具访问历史记录,如:
<强> BasicComponent.js 强>
SharedVariables
答案 5 :(得分:31)
对于这个,谁不控制服务器端,因此使用散列路由器v2:
将history放入单独的文件中(例如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 :(得分:24)
警告:此答案仅涵盖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
,否则无法访问它。
至于什么是上下文,它是一个对象,比如props,从父节点传递给子节点,但是它是隐式传递的,不必每次都重新声明道具。见https://www.tildedave.com/2014/11/15/introduction-to-contexts-in-react-js.html
答案 7 :(得分:24)
React Router V4
TL:博士;
if (navigate) {
return <Redirect to="/" push={true} />
}
简单且声明性的答案是,您需要将<Redirect to={URL} push={boolean} />
与setState()
结合使用
push:boolean - 当为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+ Property Initializers初始化状态。如果您有兴趣,请查看here。
答案 8 :(得分:20)
在一些正常工作之前,我尝试过至少10种方法!
@Felipe Skinner的withRouter
答案对我来说有点压倒性的,我不确定我是否想制作新的“ExportedWithRouter”类名。
这是最简单,最干净的方法,大约当前的React-Router 3.0.0和ES6:
React-Router 3.x.x with ES6:
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.x.x中,<Link>
组件本身正在使用router.push
,因此您可以将任何传递给<Link to=
标记的内容传递给它,例如:
this.props.router.push({pathname: '/some/path', query: {key1: 'val1', key2: 'val2'})'
答案 9 :(得分:18)
要以编程方式进行导航,您需要将新的历史记录推送到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;
答案 10 :(得分:16)
对于ES6 + React组件,以下解决方案适用于我。
我跟着Felippe skinner,但添加了一个端到端的解决方案来帮助像我这样的初学者。
以下是我使用的版本:
“react-router”:“^ 2.7.0”
“反应”:“^ 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'));
答案 11 :(得分:16)
请找到以下工作代码: 如this article中所述,这是使用react Router导航的一种非常简单的方法:
class Register extends React.Component {
state = {
toDashboard: false,
}
handleSubmit = (user) => {
saveUser(user)
.then(() => this.setState(() => ({
toDashboard: true
})))
}
render() {
if (this.state.toDashboard === true) {
return <Redirect to='/dashboard' />
}
return (
<div>
<h1>Register</h1>
<Form onSubmit={this.handleSubmit} />
</div>
)
}
}
<< strong>重定向 />是
可组合✅声明性✅用户事件->状态更改->重新呈现✅
React Router正在渲染注册组件,我们的代码可能如下所示
class Register extends React.Component {
handleSubmit = (user) => {
saveUser(user).then(() =>
this.props.history.push('/dashboard')
))
}
render() {
return (
<div>
<h1>Register</h1>
<Form onSubmit={this.handleSubmit} />
</div>
)
}
}
通过添加withRouter,看起来像这样
import {
withRouter
} from 'react-router-dom'
class Register extends React.Component {
handleSubmit = (user) => {
saveUser(user).then(() =>
this.props.history.push('/dashboard')
))
}
render() {
return (
<div>
<h1>Register</h1>
<Form onSubmit={this.handleSubmit} />
</div>
)
}
}
export default withRouter(Register)
有两种方法可以使用React Router以编程方式进行导航-和history.push。尽管我会尽量支持重定向,但您使用哪种主要取决于您和您的特定用例。
答案 12 :(得分:15)
可能不是最好的方法,但是...使用react-router v4,以下的Typescript可以给出一些想法。
在下面的渲染组件中,例如可以访问LoginPage
,router
对象,只需致电router.transitionTo('/homepage')
即可导航。
导航代码来自https://react-router.now.sh/Match。
"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')
);
答案 13 :(得分:14)
在 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);
答案 14 :(得分:12)
要将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);
答案 15 :(得分:9)
基于之前的答案
来自JoséAntonioPostigo和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”
答案 16 :(得分:9)
即将推出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是一个展示how to use/update react-router的示例应用,它包含了导航应用的示例功能测试。
答案 17 :(得分:8)
在反应路由器v4中。我按照以下两种方式以编程方式进行路由。
1. this.props.history.push("/something/something")
2. this.props.history.replace("/something/something")
第二名
替换历史记录堆栈中的当前条目
要获取道具的历史记录,您可能需要用
包装组件withRouter https://reacttraining.com/react-router/core/api/withRouter
答案 18 :(得分:7)
使用当前的React版本(15.3),Attachment
为我工作,但它显示以下警告:
browser.js:49警告:[react-router]
this.props.history.push('/location');
和 不推荐使用props.history
。请使用context.history
。
我使用context.router
解决了这个问题:
context.router
答案 19 :(得分:7)
如果您使用哈希值或浏览器历史记录,则可以执行
hashHistory.push('/login');
browserHistory.push('/login');
答案 20 :(得分:5)
React-Router V4
如果您使用的是版本4,那么您可以使用我的库(无耻插件),只需发送一个动作,一切正常!
collect_list
答案 21 :(得分:5)
更新:带有钩子的React Router v6
import {useNavigate} from 'react-router-dom';
let navigate = useNavigate();
navigate('home');
要浏览浏览器的历史记录,
navigate(-1); ---> Go back
navigate(1); ---> Go forward
navigate(-2); ---> Move two steps backward.
答案 22 :(得分:5)
在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 issues comment
答案 23 :(得分:4)
如果碰巧将RR4 w / redux与react-router-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钩子反应组件可能会更好。
答案 24 :(得分:3)
在撰写本文时,正确的答案是给我的
this.context.router.history.push('/');
但您需要将PropTypes添加到组件
Header.contextTypes = {
router: PropTypes.object.isRequired
}
export default Header;
不要忘记导入PropTypes
import PropTypes from 'prop-types';
答案 25 :(得分:3)
也许不是最好的解决方案,但它可以完成工作:
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组件中可能不需要它。
但是,通常不需要这种类型的重定向。因此,组件标记中的一个或两个额外的隐藏链接不会对此造成太大影响,特别是如果您为它们提供有意义的名称。
答案 26 :(得分:3)
您还可以在无状态组件中使用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
答案 27 :(得分:3)
尝试使用hookrouter,“ react-router的现代替代品”
https://www.npmjs.com/package/hookrouter
import { useRoutes, usePath, A} from "hookrouter";
回答关于通过选择框链接的OP问题,您可以这样做:
navigate('/about');
***更新后的答案***
我认为hook-router是一个很好的入门工具包,可以帮助我学习路由,但是此后由于其历史记录和查询参数处理而更新为react-router。
import { useLocation, useHistory } from 'react-router-dom';
const Component = (props) => {
const history = useHistory();
// Programmatically navigate
history.push(newUrlString);
}
将您要导航到location.history的位置。
答案 28 :(得分:3)
以编程方式在基于类的组件中导航。
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}/>
}
.....
.....
}
}
希望,有帮助。
答案 29 :(得分:2)
这对我有用,不需要特殊导入:
<input
type="button"
name="back"
id="back"
class="btn btn-primary"
value="Back"
onClick={() => { this.props.history.goBack() }}
/>
答案 30 :(得分:0)
对于React Router v4 +
假设您不需要在初始渲染本身期间进行导航(可以使用<Redirect>
组件),这就是我们在应用程序中所做的。
定义一个空路由,该路由返回null,这将使您能够访问历史对象。您需要在定义了Router
的顶层执行此操作。
现在您可以在history上完成所有操作,例如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>
);
}
答案 31 :(得分:0)
因此,在我的回答中,有3种不同的方式以编程方式重定向到路由。已经提供了一些解决方案,但以下解决方案仅针对 功能组件 以及其他演示应用程序。
使用以下版本:
反应: 16.12.0
反应区域: 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>
从documentation关于<HashRouter>
:
使用URL的哈希部分(即
<Router>
)使您的UI与URL保持同步的window.location.hash
。
解决方案:
<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
,从history
获取props
: 创建了一个名为WithRouterAction
的组件,显示如下:
const WithRouterAction = (props:any) => {
const { history } = props;
return <button onClick={() => { history.push('/withrouter') }}>
withRouter redirect
</button>
}
export default withRouter(WithRouterAction);
从withRouter
文档中阅读:
您可以通过
history
高阶组件访问<Route>
对象的属性和最接近的withRouter
匹配项。每当渲染时,withRouter
会将更新后的match
,location
和history
道具传递给包装的组件。
演示:
为了更好地表示,我使用以下示例构建了一个GitHub存储库,请在下面找到它:
https://github.com/norbitrial/react-router-programmatically-redirect-examples
我希望这会有所帮助!
答案 32 :(得分:0)
如果您使用的是较新版本的react,最好使用“ useHistory”挂钩
答案 33 :(得分:-1)
反应路由器域:5.1.2
此站点有3个页面,所有页面均在浏览器中动态呈现。
尽管该页面从未刷新,但请注意React Router如何 在浏览网站时使URL保持最新。这个 保留浏览器历史记录,确保背面 按钮和书签正常工作
开关会查看所有子项 元素并渲染第一个路径 与当前网址匹配。随时使用 您有多条路线,但您只想一条 一次渲染它们
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>
);
}```
答案 34 :(得分:-2)
答案 35 :(得分:-2)
只需使用this.props.history.push('/where/to/go');
答案 36 :(得分:-2)
我们可以从 index.js
开始:
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { BrowserRouter } from "react-router-dom";
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById("root")
);
reportWebVitals();
<块引用>
我一直在使用这个包:
"react-dom": "^17.0.1",
"react-router-dom": "^5.2.0",
文件 app.js
import { Switch, Route } from "react-router-dom";
class App extends React.Component {
constructor() {
super();
this.state = {
currentUser: null,
};
}
//important
unsubscribeFromAuth = null;
componetDidMount() {
this.unsubscribeFromAuth = auth.onAuthStateChanged((user) => {
this.setState({ currentUser: user });
});
}
componentWillUnmount() {
this.unsubscribeFromAuth();
}
render() {
return (
<div>
<Header currentUser />
<Switch>
<Route exact path="/" component={HomePage} />
<Route path="/shop" component={ShopPage} />
<Route path="/signin" component={SignInSignUpage} />
</Switch>
</div>
);
}
}
export default App;
exact path="/"
有助于获取准确路径,这就是我们可以轻松呈现您的页面的原因。