react-router 返回一个页面 你如何配置历史记录?
react-router go back a page how do you configure history?
谁能告诉我如何返回上一页而不是特定路线?
使用此代码时:
var BackButton = React.createClass({
mixins: [Router.Navigation],
render: function() {
return (
<button
className="button icon-left"
onClick={this.navigateBack}>
Back
</button>
);
},
navigateBack: function(){
this.goBack();
}
});
得到这个错误,goBack()被忽略,因为没有路由器历史记录
这是我的路线:
// Routing Components
Route = Router.Route;
RouteHandler = Router.RouteHandler;
DefaultRoute = Router.DefaultRoute;
var routes = (
<Route name="app" path="/" handler={OurSchoolsApp}>
<DefaultRoute name="home" handler={HomePage} />
<Route name="add-school" handler={AddSchoolPage} />
<Route name="calendar" handler={CalendarPage} />
<Route name="calendar-detail" path="calendar-detail/:id" handler={CalendarDetailPage} />
<Route name="info-detail" path="info-detail/:id" handler={InfoDetailPage} />
<Route name="info" handler={InfoPage} />
<Route name="news" handler={NewsListPage} />
<Route name="news-detail" path="news-detail/:id" handler={NewsDetailPage} />
<Route name="contacts" handler={ContactPage} />
<Route name="contact-detail" handler={ContactDetailPage} />
<Route name="settings" handler={SettingsPage} />
</Route>
);
Router.run(routes, function(Handler){
var mountNode = document.getElementById('app');
React.render(<Handler /> , mountNode);
});
我认为您只需要像这样在路由器上启用 BrowserHistory 即可:<Router history={new BrowserHistory}>
.
在此之前,您应该从 'react-router/lib/BrowserHistory'
请求 BrowserHistory
希望对您有所帮助!
更新:ES6 中的示例
const BrowserHistory = require('react-router/lib/BrowserHistory').default;
const App = React.createClass({
render: () => {
return (
<div><button onClick={BrowserHistory.goBack}>Go Back</button></div>
);
}
});
React.render((
<Router history={BrowserHistory}>
<Route path="/" component={App} />
</Router>
), document.body);
使用 React v16 和 ReactRouter v4.2.0 更新(2017 年 10 月):
class BackButton extends Component {
static contextTypes = {
router: () => true, // replace with PropTypes.object if you use them
}
render() {
return (
<button
className="button icon-left"
onClick={this.context.router.history.goBack}>
Back
</button>
)
}
}
使用 React v15 和 ReactRouter v3.0.0(2016 年 8 月)更新:
var browserHistory = ReactRouter.browserHistory;
var BackButton = React.createClass({
render: function() {
return (
<button
className="button icon-left"
onClick={browserHistory.goBack}>
Back
</button>
);
}
});
创建了一个 fiddle,其中包含带有嵌入式 iframe 的更复杂的示例:https://jsfiddle.net/kwg1da3a/
React v14 和 ReacRouter v1.0.0(2015 年 9 月 10 日)
你可以这样做:
var React = require("react");
var Router = require("react-router");
var SomePage = React.createClass({
...
contextTypes: {
router: React.PropTypes.func
},
...
handleClose: function () {
if (Router.History.length > 1) {
// this will take you back if there is history
Router.History.back();
} else {
// this will take you to the parent route if there is no history,
// but unfortunately also add it as a new route
var currentRoutes = this.context.router.getCurrentRoutes();
var routeName = currentRoutes[currentRoutes.length - 2].name;
this.context.router.transitionTo(routeName);
}
},
...
你需要小心,你有必要的历史可以回去。如果您直接点击该页面然后点击返回,它会将您带回到您的应用程序之前的浏览器历史记录中。
此解决方案将处理这两种情况。但是,它不会处理可以使用后退按钮在页面内导航(并添加到浏览器历史记录)的 iframe。坦率地说,我认为这是 react-router 中的一个错误。此处创建的问题:https://github.com/rackt/react-router/issues/1874
这是一个有效的 BackButton 组件 (React 0.14):
var React = require('react');
var Router = require('react-router');
var History = Router.History;
var BackButton = React.createClass({
mixins: [ History ],
render: function() {
return (
<button className="back" onClick={this.history.goBack}>{this.props.children}</button>
);
}
});
module.exports = BackButton;
如果没有历史,你当然可以这样做:
<button className="back" onClick={goBack}>{this.props.children}</button>
function goBack(e) {
if (/* no history */) {
e.preventDefault();
} else {
this.history.goBack();
}
}
this.context.router.goBack()
不需要导航混合!
对于 react-router v2.x 这已经改变了。这是我为 ES6 所做的:
import React from 'react';
import FontAwesome from 'react-fontawesome';
import { Router, RouterContext, Link, browserHistory } from 'react-router';
export default class Header extends React.Component {
render() {
return (
<div id="header">
<div className="header-left">
{
this.props.hasBackButton &&
<FontAwesome name="angle-left" className="back-button" onClick={this.context.router.goBack} />
}
</div>
<div>{this.props.title}</div>
</div>
)
}
}
Header.contextTypes = {
router: React.PropTypes.object
};
Header.defaultProps = {
hasBackButton: true
};
Header.propTypes = {
title: React.PropTypes.string
};
没有mixins的ES6方法使用react-router,无状态函数。
import React from 'react'
import { browserHistory } from 'react-router'
export const Test = () => (
<div className="">
<button onClick={browserHistory.goBack}>Back</button>
</div>
)
这适用于浏览器和哈希历史记录。
this.props.history.goBack();
在 react-router v4.x 中你可以使用 history.goBack
相当于 history.go(-1)
.
App.js
import React from "react";
import { render } from "react-dom";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import Home from "./Home";
import About from "./About";
import Contact from "./Contact";
import Back from "./Back";
const styles = {
fontFamily: "sans-serif",
textAlign: "left"
};
const App = () => (
<div style={styles}>
<Router>
<div>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/about">About</Link></li>
<li><Link to="/contact">Contact</Link></li>
</ul>
<hr />
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/contact" component={Contact} />
<Back />{/* <----- This is component that will render Back button */}
</div>
</Router>
</div>
);
render(<App />, document.getElementById("root"));
Back.js
import React from "react";
import { withRouter } from "react-router-dom";
const Back = ({ history }) => (
<button onClick={history.goBack}>Back to previous page</button>
);
export default withRouter(Back);
演示:
https://codesandbox.io/s/ywmvp95wpj
请记住,使用 history
您的用户可以离开,因为 history.goBack()
可以加载访问者在打开您的应用程序之前访问过的页面。
为了防止出现上述情况,我创建了一个简单的库 react-router-last-location 来监视用户的最后位置。
用法非常简单。
首先,您需要从 npm
.
安装 react-router-dom
和 react-router-last-location
npm install react-router-dom react-router-last-location --save
然后使用 LastLocationProvider
如下:
App.js
import React from "react";
import { render } from "react-dom";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import { LastLocationProvider } from "react-router-last-location";
// ↑
// |
// |
//
// Import provider
//
import Home from "./Home";
import About from "./About";
import Contact from "./Contact";
import Back from "./Back";
const styles = {
fontFamily: "sans-serif",
textAlign: "left"
};
const App = () => (
<div style={styles}>
<h5>Click on About to see your last location</h5>
<Router>
<LastLocationProvider>{/* <---- Put provider inside <Router> */}
<div>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/about">About</Link></li>
<li><Link to="/contact">Contact</Link></li>
</ul>
<hr />
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/contact" component={Contact} />
<Back />
</div>
</LastLocationProvider>
</Router>
</div>
);
render(<App />, document.getElementById("root"));
Back.js
import React from "react";
import { Link } from "react-router-dom";
import { withLastLocation } from "react-router-last-location";
// ↑
// |
// |
//
// `withLastLocation` higher order component
// will pass `lastLocation` to your component
//
// |
// |
// ↓
const Back = ({ lastLocation }) => (
lastLocation && <Link to={lastLocation || '/'}>Back to previous page</Link>
);
// Remember to wrap
// your component before exporting
//
// |
// |
// ↓
export default withLastLocation(Back);
像这样调用以下组件:
<BackButton history={this.props.history} />
这里是组件:
import React, { Component } from 'react'
import PropTypes from 'prop-types'
class BackButton extends Component {
constructor() {
super(...arguments)
this.goBack = this.goBack.bind(this)
}
render() {
return (
<button
onClick={this.goBack}>
Back
</button>
)
}
goBack() {
this.props.history.goBack()
}
}
BackButton.propTypes = {
history: PropTypes.object,
}
export default BackButton
我正在使用:
"react": "15.6.1"
"react-router": "4.2.0"
import { withRouter } from 'react-router-dom'
this.props.history.goBack();
我正在使用这些版本
"react": "^15.6.1",
"react-dom": "^15.6.1",
"react-router": "^4.2.0",
"react-router-dom": "^4.2.2",
导入withRouter
import { withRouter } from 'react-router-dom';
将组件导出为:
export withRouter(nameofcomponent)
示例,单击按钮时,调用 goBack
:
<button onClick={this.props.history.goBack}>Back</button>
在 react-router-dom
v4.3
上测试
REDUX
您还可以使用 react-router-redux
,其中包含 goBack()
和 push()
。
这是一个采样包:
在您应用程序的入口点,您需要 ConnectedRouter
,有时需要棘手的连接是 history
对象。 Redux 中间件监听历史变化:
import React from 'react'
import { render } from 'react-dom'
import { ApolloProvider } from 'react-apollo'
import { Provider } from 'react-redux'
import { ConnectedRouter } from 'react-router-redux'
import client from './components/apolloClient'
import store, { history } from './store'
import Routes from './Routes'
import './index.css'
render(
<ApolloProvider client={client}>
<Provider store={store}>
<ConnectedRouter history={history}>
<Routes />
</ConnectedRouter>
</Provider>
</ApolloProvider>,
document.getElementById('root'),
)
我将向您展示一种连接 history
的方法。请注意历史是如何导入到商店中并作为单例导出的,以便它可以在应用程序的入口点中使用:
import { createStore, applyMiddleware, compose } from 'redux'
import { routerMiddleware } from 'react-router-redux'
import thunk from 'redux-thunk'
import createHistory from 'history/createBrowserHistory'
import rootReducer from './reducers'
export const history = createHistory()
const initialState = {}
const enhancers = []
const middleware = [thunk, routerMiddleware(history)]
if (process.env.NODE_ENV === 'development') {
const { devToolsExtension } = window
if (typeof devToolsExtension === 'function') {
enhancers.push(devToolsExtension())
}
}
const composedEnhancers = compose(applyMiddleware(...middleware), ...enhancers)
const store = createStore(rootReducer, initialState, composedEnhancers)
export default store
上面的示例块显示了如何加载完成设置过程的 react-router-redux
中间件助手。
我认为下一部分完全是多余的,但我会把它包括在内,以防将来有人从中受益:
import { combineReducers } from 'redux'
import { routerReducer as routing } from 'react-router-redux'
export default combineReducers({
routing, form,
})
我一直使用 routerReducer
,因为它允许我强制重新加载通常由于 shouldComponentUpdate
而不会加载的组件。一个明显的例子是当您有一个导航栏时,它应该在用户按下 NavLink
按钮时更新。如果你沿着这条路走下去,你会了解到 Redux 的连接方法使用 shouldComponentUpdate
。使用routerReducer
,您可以使用mapStateToProps
将路由更改映射到导航栏,这将在历史对象更改时触发它更新。
像这样:
const mapStateToProps = ({ routing }) => ({ routing })
export default connect(mapStateToProps)(Nav)
请原谅我为人们添加了一些额外的关键字:如果您的组件没有正确更新,请通过删除连接功能来调查 shouldComponentUpdate
并查看它是否可以解决问题。如果是这样,请拉入 routerReducer
,组件将在 URL 更改时正确更新。
最后,完成所有这些后,您可以随时拨打 goBack()
或 push()
!
现在在一些随机组件中尝试:
- 在
connect()
中导入
- 你甚至不需要
mapStateToProps
或 mapDispatchToProps
- 在 goBack 中导入并从
react-router-redux
推送
- 呼叫
this.props.dispatch(goBack())
- 呼叫
this.props.dispatch(push('/sandwich'))
- 体验积极的情绪
如果您需要更多采样,请查看:https://www.npmjs.com/package/react-router-redux
就这么用
<span onClick={() => this.props.history.goBack()}>Back</span>
Check out my working example using React 16.0 with React-router v4. check out the code Github
使用withRouter
和history.goBack()
这就是我正在实施的想法...
History.js
import React, { Component } from 'react';
import { withRouter } from 'react-router-dom'
import './App.css'
class History extends Component {
handleBack = () => {
this.props.history.goBack()
}
handleForward = () => {
console.log(this.props.history)
this.props.history.go(+1)
}
render() {
return <div className="container">
<div className="row d-flex justify-content-between">
<span onClick={this.handleBack} className="d-flex justify-content-start button">
<i className="fas fa-arrow-alt-circle-left fa-5x"></i>
</span>
<span onClick={this.handleForward} className="d-flex justify-content-end button">
<i className="fas fa-arrow-alt-circle-right fa-5x"></i>
</span>
</div>
</div>
}
}
export default withRouter(History)
PageOne.js
import React, { Fragment, Component } from 'react'
class PageOne extends Component {
componentDidMount(){
if(this.props.location.state && this.props.location.state.from != '/pageone')
this.props.history.push({
pathname: '/pageone',
state: {
from: this.props.location.pathname
}
});
}
render() {
return (
<Fragment>
<div className="container-fluid">
<div className="row d-flex justify-content-center">
<h2>Page One</h2>
</div>
</div>
</Fragment>
)
}
}
export default PageOne
p.s。抱歉,代码太大 post 都在这里
这段代码将为您解决问题。
this.context.router.history.goBack()
对我有用的是在文件顶部导入 withRouter;
import { withRouter } from 'react-router-dom'
然后用它来包装我文件底部的导出函数;
export default withRouter(WebSitePageTitleComponent)
然后允许我访问路由器的历史记录道具。下面是完整的示例代码!
import React, { Component } from 'react'
import { withRouter } from 'react-router-dom'
import PropTypes from 'prop-types'
class TestComponent extends Component {
constructor(props) {
super(props)
this.handleClick = this.handleClick.bind(this)
}
handleClick() {
event.preventDefault()
this.props.history.goBack()
}
render() {
return (
<div className="page-title">
<a className="container" href="/location" onClick={this.handleClick}>
<h1 className="page-header">
{ this.props.title }
</h1>
</a>
</div>
)
}
}
const { string, object } = PropTypes
TestComponent.propTypes = {
title: string.isRequired,
history: object
}
export default withRouter(TestComponent)
使用 React Hooks
导入:
import { useHistory } from "react-router-dom";
在无状态组件中:
let history = useHistory();
调用事件:
history.goBack()
Button 事件中使用的示例:
<button onClick={history.goBack}>Back</button>
或
<button onClick={() => history.goBack()}>Back</button>
唯一对我有用的解决方案是最简单的。无需额外导入。
<a href="#" onClick={() => this.props.history.goBack()}>Back</a>
谢谢,IamMHussain
根据https://reacttraining.com/react-router/web/api/history
对于"react-router-dom": "^5.1.2",
、
const { history } = this.props;
<Button onClick={history.goBack}>
Back
</Button>
YourComponent.propTypes = {
history: PropTypes.shape({
goBack: PropTypes.func.isRequired,
}).isRequired,
};
返回特定页面:
import { useHistory } from "react-router-dom";
const history = useHistory();
const routeChange = () => {
let path = '/login';
history.push(path);
};
返回上一个页面:
import { useHistory } from "react-router-dom";
const history = useHistory();
const routeChange = () => {
history.goBack()
};
React Router v6
useNavigate
Hook是现在推荐的回退方式:
import { useNavigate } from 'react-router-dom';
function App() {
const navigate = useNavigate();
return (
<>
<button onClick={() => navigate(-1)}>go back</button>
<button onClick={() => navigate(1)}>go forward</button>
</>
);
}
Go back/forward 多个历史堆栈条目:
<button onClick={() => navigate(-2)}>go two back</button>
<button onClick={() => navigate(2)}>go two forward</button>
进入具体路线:
navigate("users") // go to users route, like history.push
navigate("users", { replace: true }) // go to users route, like history.replace
navigate("users", { state }) // go to users route, pass some state in
useNavigate
replaces useHistory
to support 即将到来的 React Suspense/Concurrent 模式更好。
React Router 使用 HTML5 历史记录 API,它建立在浏览器历史记录 API 的基础上,以提供我们可以在 React 应用程序中轻松使用的界面。 History API。因此无需导入任何内容(useHistory 等)
对于功能组件:
<button onClick={()=>{ window.history.back() }}> Back </button>
对于 class 组件:
<button onClick={()=>{ this.window.history.back() }}> Back </button>
第一步
import { useHistory } from "react-router-dom";`
第 2 步
let history = useHistory();
第 3 步
const goToPreviousPath = (e) => {
e.preventDefault();
history.goBack()
}
第四步
<Button
onClick={goToPreviousPath}
>
Back
</Button>
他react-router-dom
v6
import { useNavigate } from 'react-router-dom';
function goBack() {
const navigate = useNavigate();
return <button onClick={() => navigate(-1)}>go back</button>
}
我想稍微更新一下之前的答案。
如果您使用 react-router >v6.0
,那么 useHistory()
不是返回的正确方法。你会得到一个错误,因为我猜 useHistory()
在最新版本中不存在。
所以这是更新后的答案
// This is a React Router v6 app
import { useNavigate } from "react-router-dom";
function App() {
const navigate = useNavigate();
return (
<>
<button onClick={() => navigate(-2)}>
Go 2 pages back
</button>
<button onClick={() => navigate(-1)}>Go back</button>
<button onClick={() => navigate(1)}>
Go forward
</button>
<button onClick={() => navigate(2)}>
Go 2 pages forward
</button>
</>
);
}
使用这个 useNavigate()
钩子。
您可以在此处阅读有关从 v5
到 v6
的转换的官方文档
https://reactrouter.com/docs/en/v6/upgrading/v5
谁能告诉我如何返回上一页而不是特定路线?
使用此代码时:
var BackButton = React.createClass({
mixins: [Router.Navigation],
render: function() {
return (
<button
className="button icon-left"
onClick={this.navigateBack}>
Back
</button>
);
},
navigateBack: function(){
this.goBack();
}
});
得到这个错误,goBack()被忽略,因为没有路由器历史记录
这是我的路线:
// Routing Components
Route = Router.Route;
RouteHandler = Router.RouteHandler;
DefaultRoute = Router.DefaultRoute;
var routes = (
<Route name="app" path="/" handler={OurSchoolsApp}>
<DefaultRoute name="home" handler={HomePage} />
<Route name="add-school" handler={AddSchoolPage} />
<Route name="calendar" handler={CalendarPage} />
<Route name="calendar-detail" path="calendar-detail/:id" handler={CalendarDetailPage} />
<Route name="info-detail" path="info-detail/:id" handler={InfoDetailPage} />
<Route name="info" handler={InfoPage} />
<Route name="news" handler={NewsListPage} />
<Route name="news-detail" path="news-detail/:id" handler={NewsDetailPage} />
<Route name="contacts" handler={ContactPage} />
<Route name="contact-detail" handler={ContactDetailPage} />
<Route name="settings" handler={SettingsPage} />
</Route>
);
Router.run(routes, function(Handler){
var mountNode = document.getElementById('app');
React.render(<Handler /> , mountNode);
});
我认为您只需要像这样在路由器上启用 BrowserHistory 即可:<Router history={new BrowserHistory}>
.
在此之前,您应该从 'react-router/lib/BrowserHistory'
BrowserHistory
希望对您有所帮助!
更新:ES6 中的示例
const BrowserHistory = require('react-router/lib/BrowserHistory').default;
const App = React.createClass({
render: () => {
return (
<div><button onClick={BrowserHistory.goBack}>Go Back</button></div>
);
}
});
React.render((
<Router history={BrowserHistory}>
<Route path="/" component={App} />
</Router>
), document.body);
使用 React v16 和 ReactRouter v4.2.0 更新(2017 年 10 月):
class BackButton extends Component {
static contextTypes = {
router: () => true, // replace with PropTypes.object if you use them
}
render() {
return (
<button
className="button icon-left"
onClick={this.context.router.history.goBack}>
Back
</button>
)
}
}
使用 React v15 和 ReactRouter v3.0.0(2016 年 8 月)更新:
var browserHistory = ReactRouter.browserHistory;
var BackButton = React.createClass({
render: function() {
return (
<button
className="button icon-left"
onClick={browserHistory.goBack}>
Back
</button>
);
}
});
创建了一个 fiddle,其中包含带有嵌入式 iframe 的更复杂的示例:https://jsfiddle.net/kwg1da3a/
React v14 和 ReacRouter v1.0.0(2015 年 9 月 10 日)
你可以这样做:
var React = require("react");
var Router = require("react-router");
var SomePage = React.createClass({
...
contextTypes: {
router: React.PropTypes.func
},
...
handleClose: function () {
if (Router.History.length > 1) {
// this will take you back if there is history
Router.History.back();
} else {
// this will take you to the parent route if there is no history,
// but unfortunately also add it as a new route
var currentRoutes = this.context.router.getCurrentRoutes();
var routeName = currentRoutes[currentRoutes.length - 2].name;
this.context.router.transitionTo(routeName);
}
},
...
你需要小心,你有必要的历史可以回去。如果您直接点击该页面然后点击返回,它会将您带回到您的应用程序之前的浏览器历史记录中。
此解决方案将处理这两种情况。但是,它不会处理可以使用后退按钮在页面内导航(并添加到浏览器历史记录)的 iframe。坦率地说,我认为这是 react-router 中的一个错误。此处创建的问题:https://github.com/rackt/react-router/issues/1874
这是一个有效的 BackButton 组件 (React 0.14):
var React = require('react');
var Router = require('react-router');
var History = Router.History;
var BackButton = React.createClass({
mixins: [ History ],
render: function() {
return (
<button className="back" onClick={this.history.goBack}>{this.props.children}</button>
);
}
});
module.exports = BackButton;
如果没有历史,你当然可以这样做:
<button className="back" onClick={goBack}>{this.props.children}</button>
function goBack(e) {
if (/* no history */) {
e.preventDefault();
} else {
this.history.goBack();
}
}
this.context.router.goBack()
不需要导航混合!
对于 react-router v2.x 这已经改变了。这是我为 ES6 所做的:
import React from 'react';
import FontAwesome from 'react-fontawesome';
import { Router, RouterContext, Link, browserHistory } from 'react-router';
export default class Header extends React.Component {
render() {
return (
<div id="header">
<div className="header-left">
{
this.props.hasBackButton &&
<FontAwesome name="angle-left" className="back-button" onClick={this.context.router.goBack} />
}
</div>
<div>{this.props.title}</div>
</div>
)
}
}
Header.contextTypes = {
router: React.PropTypes.object
};
Header.defaultProps = {
hasBackButton: true
};
Header.propTypes = {
title: React.PropTypes.string
};
没有mixins的ES6方法使用react-router,无状态函数。
import React from 'react'
import { browserHistory } from 'react-router'
export const Test = () => (
<div className="">
<button onClick={browserHistory.goBack}>Back</button>
</div>
)
这适用于浏览器和哈希历史记录。
this.props.history.goBack();
在 react-router v4.x 中你可以使用 history.goBack
相当于 history.go(-1)
.
App.js
import React from "react";
import { render } from "react-dom";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import Home from "./Home";
import About from "./About";
import Contact from "./Contact";
import Back from "./Back";
const styles = {
fontFamily: "sans-serif",
textAlign: "left"
};
const App = () => (
<div style={styles}>
<Router>
<div>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/about">About</Link></li>
<li><Link to="/contact">Contact</Link></li>
</ul>
<hr />
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/contact" component={Contact} />
<Back />{/* <----- This is component that will render Back button */}
</div>
</Router>
</div>
);
render(<App />, document.getElementById("root"));
Back.js
import React from "react";
import { withRouter } from "react-router-dom";
const Back = ({ history }) => (
<button onClick={history.goBack}>Back to previous page</button>
);
export default withRouter(Back);
演示: https://codesandbox.io/s/ywmvp95wpj
请记住,使用 history
您的用户可以离开,因为 history.goBack()
可以加载访问者在打开您的应用程序之前访问过的页面。
为了防止出现上述情况,我创建了一个简单的库 react-router-last-location 来监视用户的最后位置。
用法非常简单。
首先,您需要从 npm
.
react-router-dom
和 react-router-last-location
npm install react-router-dom react-router-last-location --save
然后使用 LastLocationProvider
如下:
App.js
import React from "react";
import { render } from "react-dom";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import { LastLocationProvider } from "react-router-last-location";
// ↑
// |
// |
//
// Import provider
//
import Home from "./Home";
import About from "./About";
import Contact from "./Contact";
import Back from "./Back";
const styles = {
fontFamily: "sans-serif",
textAlign: "left"
};
const App = () => (
<div style={styles}>
<h5>Click on About to see your last location</h5>
<Router>
<LastLocationProvider>{/* <---- Put provider inside <Router> */}
<div>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/about">About</Link></li>
<li><Link to="/contact">Contact</Link></li>
</ul>
<hr />
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/contact" component={Contact} />
<Back />
</div>
</LastLocationProvider>
</Router>
</div>
);
render(<App />, document.getElementById("root"));
Back.js
import React from "react";
import { Link } from "react-router-dom";
import { withLastLocation } from "react-router-last-location";
// ↑
// |
// |
//
// `withLastLocation` higher order component
// will pass `lastLocation` to your component
//
// |
// |
// ↓
const Back = ({ lastLocation }) => (
lastLocation && <Link to={lastLocation || '/'}>Back to previous page</Link>
);
// Remember to wrap
// your component before exporting
//
// |
// |
// ↓
export default withLastLocation(Back);
像这样调用以下组件:
<BackButton history={this.props.history} />
这里是组件:
import React, { Component } from 'react'
import PropTypes from 'prop-types'
class BackButton extends Component {
constructor() {
super(...arguments)
this.goBack = this.goBack.bind(this)
}
render() {
return (
<button
onClick={this.goBack}>
Back
</button>
)
}
goBack() {
this.props.history.goBack()
}
}
BackButton.propTypes = {
history: PropTypes.object,
}
export default BackButton
我正在使用:
"react": "15.6.1"
"react-router": "4.2.0"
import { withRouter } from 'react-router-dom'
this.props.history.goBack();
我正在使用这些版本
"react": "^15.6.1",
"react-dom": "^15.6.1",
"react-router": "^4.2.0",
"react-router-dom": "^4.2.2",
导入
withRouter
import { withRouter } from 'react-router-dom';
将组件导出为:
export withRouter(nameofcomponent)
示例,单击按钮时,调用
goBack
:<button onClick={this.props.history.goBack}>Back</button>
在 react-router-dom
v4.3
REDUX
您还可以使用 react-router-redux
,其中包含 goBack()
和 push()
。
这是一个采样包:
在您应用程序的入口点,您需要 ConnectedRouter
,有时需要棘手的连接是 history
对象。 Redux 中间件监听历史变化:
import React from 'react'
import { render } from 'react-dom'
import { ApolloProvider } from 'react-apollo'
import { Provider } from 'react-redux'
import { ConnectedRouter } from 'react-router-redux'
import client from './components/apolloClient'
import store, { history } from './store'
import Routes from './Routes'
import './index.css'
render(
<ApolloProvider client={client}>
<Provider store={store}>
<ConnectedRouter history={history}>
<Routes />
</ConnectedRouter>
</Provider>
</ApolloProvider>,
document.getElementById('root'),
)
我将向您展示一种连接 history
的方法。请注意历史是如何导入到商店中并作为单例导出的,以便它可以在应用程序的入口点中使用:
import { createStore, applyMiddleware, compose } from 'redux'
import { routerMiddleware } from 'react-router-redux'
import thunk from 'redux-thunk'
import createHistory from 'history/createBrowserHistory'
import rootReducer from './reducers'
export const history = createHistory()
const initialState = {}
const enhancers = []
const middleware = [thunk, routerMiddleware(history)]
if (process.env.NODE_ENV === 'development') {
const { devToolsExtension } = window
if (typeof devToolsExtension === 'function') {
enhancers.push(devToolsExtension())
}
}
const composedEnhancers = compose(applyMiddleware(...middleware), ...enhancers)
const store = createStore(rootReducer, initialState, composedEnhancers)
export default store
上面的示例块显示了如何加载完成设置过程的 react-router-redux
中间件助手。
我认为下一部分完全是多余的,但我会把它包括在内,以防将来有人从中受益:
import { combineReducers } from 'redux'
import { routerReducer as routing } from 'react-router-redux'
export default combineReducers({
routing, form,
})
我一直使用 routerReducer
,因为它允许我强制重新加载通常由于 shouldComponentUpdate
而不会加载的组件。一个明显的例子是当您有一个导航栏时,它应该在用户按下 NavLink
按钮时更新。如果你沿着这条路走下去,你会了解到 Redux 的连接方法使用 shouldComponentUpdate
。使用routerReducer
,您可以使用mapStateToProps
将路由更改映射到导航栏,这将在历史对象更改时触发它更新。
像这样:
const mapStateToProps = ({ routing }) => ({ routing })
export default connect(mapStateToProps)(Nav)
请原谅我为人们添加了一些额外的关键字:如果您的组件没有正确更新,请通过删除连接功能来调查 shouldComponentUpdate
并查看它是否可以解决问题。如果是这样,请拉入 routerReducer
,组件将在 URL 更改时正确更新。
最后,完成所有这些后,您可以随时拨打 goBack()
或 push()
!
现在在一些随机组件中尝试:
- 在
connect()
中导入
- 你甚至不需要
mapStateToProps
或mapDispatchToProps
- 在 goBack 中导入并从
react-router-redux
推送
- 呼叫
this.props.dispatch(goBack())
- 呼叫
this.props.dispatch(push('/sandwich'))
- 体验积极的情绪
如果您需要更多采样,请查看:https://www.npmjs.com/package/react-router-redux
就这么用
<span onClick={() => this.props.history.goBack()}>Back</span>
Check out my working example using React 16.0 with React-router v4. check out the code Github
使用withRouter
和history.goBack()
这就是我正在实施的想法...
History.js
import React, { Component } from 'react';
import { withRouter } from 'react-router-dom'
import './App.css'
class History extends Component {
handleBack = () => {
this.props.history.goBack()
}
handleForward = () => {
console.log(this.props.history)
this.props.history.go(+1)
}
render() {
return <div className="container">
<div className="row d-flex justify-content-between">
<span onClick={this.handleBack} className="d-flex justify-content-start button">
<i className="fas fa-arrow-alt-circle-left fa-5x"></i>
</span>
<span onClick={this.handleForward} className="d-flex justify-content-end button">
<i className="fas fa-arrow-alt-circle-right fa-5x"></i>
</span>
</div>
</div>
}
}
export default withRouter(History)
PageOne.js
import React, { Fragment, Component } from 'react'
class PageOne extends Component {
componentDidMount(){
if(this.props.location.state && this.props.location.state.from != '/pageone')
this.props.history.push({
pathname: '/pageone',
state: {
from: this.props.location.pathname
}
});
}
render() {
return (
<Fragment>
<div className="container-fluid">
<div className="row d-flex justify-content-center">
<h2>Page One</h2>
</div>
</div>
</Fragment>
)
}
}
export default PageOne
p.s。抱歉,代码太大 post 都在这里
这段代码将为您解决问题。
this.context.router.history.goBack()
对我有用的是在文件顶部导入 withRouter;
import { withRouter } from 'react-router-dom'
然后用它来包装我文件底部的导出函数;
export default withRouter(WebSitePageTitleComponent)
然后允许我访问路由器的历史记录道具。下面是完整的示例代码!
import React, { Component } from 'react'
import { withRouter } from 'react-router-dom'
import PropTypes from 'prop-types'
class TestComponent extends Component {
constructor(props) {
super(props)
this.handleClick = this.handleClick.bind(this)
}
handleClick() {
event.preventDefault()
this.props.history.goBack()
}
render() {
return (
<div className="page-title">
<a className="container" href="/location" onClick={this.handleClick}>
<h1 className="page-header">
{ this.props.title }
</h1>
</a>
</div>
)
}
}
const { string, object } = PropTypes
TestComponent.propTypes = {
title: string.isRequired,
history: object
}
export default withRouter(TestComponent)
使用 React Hooks
导入:
import { useHistory } from "react-router-dom";
在无状态组件中:
let history = useHistory();
调用事件:
history.goBack()
Button 事件中使用的示例:
<button onClick={history.goBack}>Back</button>
或
<button onClick={() => history.goBack()}>Back</button>
唯一对我有用的解决方案是最简单的。无需额外导入。
<a href="#" onClick={() => this.props.history.goBack()}>Back</a>
谢谢,IamMHussain
根据https://reacttraining.com/react-router/web/api/history
对于"react-router-dom": "^5.1.2",
、
const { history } = this.props;
<Button onClick={history.goBack}>
Back
</Button>
YourComponent.propTypes = {
history: PropTypes.shape({
goBack: PropTypes.func.isRequired,
}).isRequired,
};
返回特定页面:
import { useHistory } from "react-router-dom";
const history = useHistory();
const routeChange = () => {
let path = '/login';
history.push(path);
};
返回上一个页面:
import { useHistory } from "react-router-dom";
const history = useHistory();
const routeChange = () => {
history.goBack()
};
React Router v6
useNavigate
Hook是现在推荐的回退方式:
import { useNavigate } from 'react-router-dom';
function App() {
const navigate = useNavigate();
return (
<>
<button onClick={() => navigate(-1)}>go back</button>
<button onClick={() => navigate(1)}>go forward</button>
</>
);
}
Go back/forward 多个历史堆栈条目:
<button onClick={() => navigate(-2)}>go two back</button>
<button onClick={() => navigate(2)}>go two forward</button>
进入具体路线:
navigate("users") // go to users route, like history.push
navigate("users", { replace: true }) // go to users route, like history.replace
navigate("users", { state }) // go to users route, pass some state in
useNavigate
replaces useHistory
to support 即将到来的 React Suspense/Concurrent 模式更好。
React Router 使用 HTML5 历史记录 API,它建立在浏览器历史记录 API 的基础上,以提供我们可以在 React 应用程序中轻松使用的界面。 History API。因此无需导入任何内容(useHistory 等)
对于功能组件:
<button onClick={()=>{ window.history.back() }}> Back </button>
对于 class 组件:
<button onClick={()=>{ this.window.history.back() }}> Back </button>
第一步
import { useHistory } from "react-router-dom";`
第 2 步
let history = useHistory();
第 3 步
const goToPreviousPath = (e) => {
e.preventDefault();
history.goBack()
}
第四步
<Button
onClick={goToPreviousPath}
>
Back
</Button>
他react-router-dom
v6
import { useNavigate } from 'react-router-dom';
function goBack() {
const navigate = useNavigate();
return <button onClick={() => navigate(-1)}>go back</button>
}
我想稍微更新一下之前的答案。
如果您使用 react-router >v6.0
,那么 useHistory()
不是返回的正确方法。你会得到一个错误,因为我猜 useHistory()
在最新版本中不存在。
所以这是更新后的答案
// This is a React Router v6 app
import { useNavigate } from "react-router-dom";
function App() {
const navigate = useNavigate();
return (
<>
<button onClick={() => navigate(-2)}>
Go 2 pages back
</button>
<button onClick={() => navigate(-1)}>Go back</button>
<button onClick={() => navigate(1)}>
Go forward
</button>
<button onClick={() => navigate(2)}>
Go 2 pages forward
</button>
</>
);
}
使用这个 useNavigate()
钩子。
您可以在此处阅读有关从 v5
到 v6
的转换的官方文档
https://reactrouter.com/docs/en/v6/upgrading/v5