使用 react-router
,我可以使用 Link
元素创建由 react 路由器本地处理的链接。
我在内部看到它调用 this.context.transitionTo(...)
。
我想做一个导航。不是来自链接,而是来自下拉选择(例如)。我怎样才能在代码中做到这一点? this.context
是什么?
我看到了 Navigation
mixin,但是没有 mixins
我可以这样做吗?
带有钩子的 React Router v5.1.0
如果您使用 React >16.8.0 和功能组件,React Router >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>
);
}
反应路由器 v4
使用 React Router v4,您可以采用三种方法在组件内进行编程路由。
使用 withRouter 高阶组件。使用合成并渲染一个
React Router 主要是对 history
库的封装。 history
使用浏览器的浏览器和哈希历史记录为您处理与浏览器的 window.history
的交互。它还提供了一个内存历史记录,这对于没有全局历史记录的环境很有用。这在移动应用程序开发 (react-native
) 和使用 Node.js 的单元测试中特别有用。
history
实例有两种导航方法:push
和 replace
。如果您将 history
视为已访问位置的数组,则 push
将向数组中添加一个新位置,而 replace
将用新位置替换数组中的当前位置。通常,您在导航时会希望使用 push
方法。
在早期版本的 React Router 中,您必须创建自己的 history
实例,但在 v4 中,<BrowserRouter>
、<HashRouter>
和 <MemoryRouter>
组件将为您创建浏览器、哈希和内存实例。 React Router 使与您的路由器关联的 history
实例的属性和方法可通过上下文在 router
对象下使用。
1.使用withRouter高阶组件
withRouter
高阶组件将注入 history
对象作为组件的 prop。这允许您访问 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>
))
2. 使用合成并渲染一个
<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 的 context 模型感到满意时才应该使用的选项(React 的 Context API 从 v16 开始是稳定的)。
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 是实现起来最简单的选择,因此对于大多数用例来说,它们是您最好的选择。
React-Router v6+ 答案
您可以使用新的 useNavigate
挂钩。 useNavigate
钩子返回一个可用于编程导航的函数。来自反应路由器 documentaion 的示例
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 });
}
return <form onSubmit={handleSubmit}>{/* ... */}</form>;
}
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')
进一步阅读:Histories 和 Navigation
React-Router 1.xx 答案
我不会详细介绍升级细节。您可以在 Upgrade Guide
这里关于问题的主要变化是从 Navigation mixin 到 History 的变化。现在它正在使用浏览器 historyAPI 来更改路由,所以从现在开始我们将使用 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
作为属性向下传递。
您可以在他们的 1.0.x documentation 上阅读有关新版本的更多信息
这里是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
};
React-Router-Redux 注意:如果你使用的是 Redux,还有另一个名为 React-Router-Redux 的项目为你提供了 ReactRouter 的 redux 绑定,使用的方法与 React-Redux 的做法有些相同
React-Router-Redux 有一些可用的方法允许从内部动作创建者进行简单的导航。这些对于在 React Native 中拥有现有架构的人特别有用,并且他们希望在 React Web 中以最小的样板开销使用相同的模式。
探索以下方法:
推(位置)
替换(位置)
去(数)
回去()
直走()
以下是使用 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>
{ replace: true }
并且不刷新页面。
replace: state
的目的或预期行为。
反应路由器 v2
对于最新版本 (v2.0.0-rc5
),推荐的导航方法是直接推送到历史单例。您可以在 Navigating outside of 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,而不是实际导航到页面。
import { browserHistory } from './react-router'
,而是使用 import createBrowserHistory from 'history/lib/createBrowserHistory'
创建历史记录。稍后,您可以从 components 属性访问 history
:this.props.history('/some/path')
React-Router 4.x 答案
就我而言,我喜欢拥有一个甚至可以在外部组件中携带的历史对象。我喜欢有一个单独的 history.js 文件,我可以按需导入,然后对其进行操作。
您只需将 BrowserRouter
更改为 Router,并指定 history 属性。这对您没有任何改变,只是您拥有自己的历史对象,您可以根据需要进行操作。
您需要安装 react-router
使用的库 history。
示例用法,ES6 表示法:
历史.js
import createBrowserHistory from 'history/createBrowserHistory'
export default createBrowserHistory()
基本组件.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 访问历史记录,如下所示:
基本组件.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>;
}
}
以下是使用 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
}
对于这个,谁不控制服务器端,因此使用哈希路由器 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()
}
})
反应路由器 v6
我有一段时间没有接触 React,但要感谢并强调 the comment below by Shimrit Snapir:
在 React-Router 6.0 上
反应路由器 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。
警告:此答案仅涵盖 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 一样,从 parent 传给 child,但它是隐式传递的,不需要每次都重新声明 props。请参阅https://www.tildedave.com/2014/11/15/introduction-to-contexts-in-react-js.html
这是最简单和最干净的方法,大约是当前的 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'})'
要以编程方式进行导航,您需要将新的 history 推送到 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;
对于 ES6 + React 组件,以下解决方案对我有用。
我跟随 Felippe skinner,但添加了端到端的解决方案来帮助像我这样的初学者。
以下是我使用的版本:
“反应路由器”:“^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'));
这可能不是最好的方法,但是......使用 react-router v4,下面的 TypeScript 代码可以为一些人提供一个想法。
在下面呈现的组件中,例如 LoginPage
,router
对象是可访问的,只需调用 router.transitionTo('/homepage')
即可导航。
使用导航代码 from。
"react-router": "^4.0.0-2",
"react": "^15.3.1",
从 'react-router/BrowserRouter' 导入路由器;从'react-history/BrowserHistory'导入{历史};从“历史/createBrowserHistory”导入 createHistory;常量历史 = createHistory(); interface MatchWithPropsInterface { component: typeof React.Component, router: Router, history: History, 究竟是什么?: any, pattern: string } class MatchWithProps extends React.Component
在 React Router v4 中,我遵循这两种方式以编程方式进行路由。
this.props.history.push("/something/something") this.props.history.replace("/something/something")
第二
替换历史堆栈上的当前条目
要获取 props 中的历史记录,您可能必须使用
带路由器
在 React 路由器 v6 中
import { useNavigate } from "react-router-dom";
function Invoices() {
let navigate = useNavigate();
return (
<div>
<NewInvoiceForm
onSubmit={async event => {
let newInvoice = await createInvoice(event.target);
navigate(`/invoices/${newInvoice.id}`);
}}
/>
</div>
);
}
Getting Started with React Router v6
在 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);
要将 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-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 的示例应用程序,它包含导航应用程序的示例功能测试。
基于之前的 answers from José Antonio Postigo and Ben Wheeler:
新奇之处?用 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
*/
@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。
“反应路由器”:“^3.0.0”和“@types/反应路由器”:“^2.0.41”
对于那些已经在使用 React Router v6 的人,这可以使用 react-router
提供的 useNavigate
钩子来完成。
使用这个钩子导航非常简单:
import { generatePath, useNavigate } from 'react-router';
navigate(-1); // navigates back
navigate('/my/path'); // navigates to a specific path
navigate(generatePath('my/path/:id', { id: 1 })); // navigates to a dynamic path, generatePath is very useful for url replacements
对于当前的 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;
如果您使用的是哈希或浏览器历史记录,那么您可以这样做
hashHistory.push('/login');
browserHistory.push('/login');
带有钩子的 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.
那些在 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 rerender Test component
感谢 GitHub 上的这条评论:ReactTraining issues comment
您还可以在无状态组件中使用 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
对于最新的 react-router-dom v6
useHistory()
替换为 useNavigate()
。
你需要使用:
import { useNavigate } from 'react-router-dom';
const navigate = useNavigate();
navigate('/your-page-link');
以编程方式在基于类的组件中导航。
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}/>
}
.....
.....
}
}
在撰写本文时,正确答案对我来说是
this.context.router.history.push('/');
但是您需要将 PropTypes 添加到您的组件中
Header.contextTypes = {
router: PropTypes.object.isRequired
}
export default Header;
不要忘记导入 PropTypes
import PropTypes from 'prop-types';
在我的回答中,有三种不同的方式可以以编程方式重定向到路由。一些解决方案已经介绍过,但以下解决方案仅针对具有附加演示应用程序的功能组件。
使用以下版本:
反应:16.13.1 反应域:16.13.1 反应路由器:5.2.0 反应路由器域: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>
从 the documentation 到 <HashRouter>
:
解决方案:
使用
在功能组件(我的存储库中的 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 committing 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>
文档:
渲染
使用 useHistory 钩子:
在我的解决方案中有一个名为 UseHistoryAction
的组件,它代表以下内容:
let history = useHistory();
return <button onClick={() => { history.push('/usehistory') }}>
useHistory redirect
</button>
useHistory 钩子让我们可以访问历史对象,这有助于我们以编程方式导航或更改路线。
使用 withRouter,从 props 中获取历史记录:
创建了一个名为 WithRouterAction
的组件,显示如下:
const WithRouterAction = (props:any) => {
const { history } = props;
return <button onClick={() => { history.push('/withrouter') }}>
withRouter redirect
</button>
}
export default withRouter(WithRouterAction);
从 withRouter
文档中读取:
您可以通过 withRouter 高阶组件访问历史对象的属性和最近的
演示:
为了更好地表示我已经用这些示例构建了一个 GitHub 存储库,请在下面找到它:
React Router Programmatically Redirect Examples
也许不是最好的解决方案,但它可以完成工作:
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 组件中可能是不希望的。
尽管如此,这种类型的重定向并不经常需要。因此,组件标记中的一两个额外的隐藏链接不会造成太大伤害,尤其是如果您给它们起有意义的名称。
如果您碰巧通过 react-router-redux 将 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
而不是将history
传递给我的所有组件?? Gahh 我需要花更多时间阅读文档......history.push('/new-location')
?context
不再是实验性的。