react-router返回页面如何配置历史记录?

Bom*_*ber 94 javascript reactjs react-router

任何人都可以告诉我如何回到上一页而不是特定的路线?

使用此代码时:

var BackButton = React.createClass({

 mixins: [Router.Navigation],
  render: function() {
    return (
        <button
            className="button icon-left"
            onClick={this.navigateBack}>
            Back
        </button>
    );
  },

  navigateBack: function(){
    this.goBack();
  }
});
Run Code Online (Sandbox Code Playgroud)

得到此错误,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);
 });
Run Code Online (Sandbox Code Playgroud)

mlu*_*noe 87

使用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>
    )
  }
}
Run Code Online (Sandbox Code Playgroud)

使用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>
    );
  }
});
Run Code Online (Sandbox Code Playgroud)

使用嵌入式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);
    }
  },
  ...
Run Code Online (Sandbox Code Playgroud)

你需要小心,你有必要的历史回去.如果您直接点击该页面然后回来,它会在您的应用程序之前返回浏览器历史记录.

该解决方案将处理这两种情况.但是,它不会使用后退按钮处理可以在页面中导航(并添加到浏览器历史记录)的iframe.坦率地说,我认为这是react-router中的一个错误.在此处创建的问题:https://github.com/rackt/react-router/issues/1874

  • 另外,根据设置,可能会使用 this.props.history.goBack 而不是 this.context.router.history.goBack (2认同)

Eri*_*rto 83

使用 React 钩子

进口:

import { useHistory } from "react-router-dom";
Run Code Online (Sandbox Code Playgroud)

在无状态组件中:

let history = useHistory();
Run Code Online (Sandbox Code Playgroud)

调用事件:

history.goBack()
Run Code Online (Sandbox Code Playgroud)

在事件按钮中使用的示例:

<button onClick={history.goBack}>Back</button>
Run Code Online (Sandbox Code Playgroud)

或者

<button onClick={() => history.goBack()}>Back</button>
Run Code Online (Sandbox Code Playgroud)

  • “useHistory”未从“react-router-dom”导出。 (14认同)
  • &lt;button onClick={() =&gt; History.goBack()}&gt;后退&lt;/button&gt; (5认同)

小智 40

this.context.router.goBack()
Run Code Online (Sandbox Code Playgroud)

无需导航mixin!

  • 使用react-router-dom:"v4.2.2"和`react {withRouter}来自'react-router-dom';`使用`this.props.history.goBack();` (12认同)

小智 37

  1. 进口 withRouter

    import { withRouter } from 'react-router-dom';
    
    Run Code Online (Sandbox Code Playgroud)
  2. 将组件导出为:

    export withRouter(nameofcomponent) 
    
    Run Code Online (Sandbox Code Playgroud)
  3. 例如,点击按钮,调用goBack:

    <button onClick={this.props.history.goBack}>Back</button>
    
    Run Code Online (Sandbox Code Playgroud)

react-router-domv4.3上测试过

  • 顺便说一句,即使不导入或使用`withRouter`,它也适用于我。也许我们只是使用浏览器历史原生 API。但是这样好吗?? (2认同)
  • 这是一个很好的解决方案。当用户使用直接 URL 登陆页面时唯一的问题 -&gt; 它会破坏应用程序,因为它没有历史记录。 (2认同)
  • 最好的解释在这里 (2认同)

小智 36

我认为您只需要在路由器上启用BrowserHistory,就像它那样初始化:<Router history={new BrowserHistory}>.

在此之前,您应该需要BrowserHistory'react-router/lib/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);
Run Code Online (Sandbox Code Playgroud)

  • 这是正确的答案?这甚至都没有回答这个问题.@轰炸机 (17认同)
  • 对于读这篇文章的人.如果要从子组件执行此操作.你可以在`this.props.history`找到历史对象.所以,代码变成了'this.props.history.goBack` (10认同)
  • 如何反应路由器4?我认为它不再支持BrowserHistory. (3认同)
  • 从react-router-dom版本5开始,历史记录是由BrowserRouter隐式创建的,并且可以通过props使用,您可以通过props.history访问它。 (3认同)

pto*_*son 31

没有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>
)
Run Code Online (Sandbox Code Playgroud)

  • 我在尝试你的解决方案时收到浏览器警告:'react-router'`中找不到`export'laserHistory' (2认同)
  • browserHistory仅存在于v2和v3中.如果你使用v4,你应该阅读迁移指南:https://github.com/ReactTraining/react-router/blob/25776d4dc89b8fb2f575884749766355992116b5/packages/react-router/docs/guides/migrating.md#the-router (2认同)

dha*_*ahn 22

返回特定页面

  import { useHistory } from "react-router-dom";

  const history = useHistory();
  
  const routeChange = () => {
    let path = '/login';
    history.push(path);
  };
Run Code Online (Sandbox Code Playgroud)

返回上一页

  import { useHistory } from "react-router-dom";

  const history = useHistory();
  
  const routeChange = () => {
    history.goBack()
  };
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,这是一个很棒的 2020 年答案!接受的答案是2015年。 (3认同)

小智 10

我想稍微更新一下之前的答案。如果您正在使用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>
    </>
  );
}
Run Code Online (Sandbox Code Playgroud)

使用这个useNavigate()钩子。您可以在此处 v5阅读此过渡的官方文档https://reactrouter.com/docs/en/v6/upgrading/v5v6


Mor*_*s S 9

使用React 16.0和React-router v4 Live Example查看我的工作示例.看看代码Github

使用withRouterhistory.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)
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

抱歉,代码很大,可以在这里发布


ngs*_*chr 7

这是一个有效的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;
Run Code Online (Sandbox Code Playgroud)

如果没有历史记录,你可以选择这样做:

<button className="back" onClick={goBack}>{this.props.children}</button>

function goBack(e) {
  if (/* no history */) {
    e.preventDefault();
  } else {
    this.history.goBack();
  }
}
Run Code Online (Sandbox Code Playgroud)


ace*_*des 7

对于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
};
Run Code Online (Sandbox Code Playgroud)


hin*_*nok 7

在 react-router v4.x 中,您可以使用history.goBack等效于history.go(-1).

应用程序.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"));
Run Code Online (Sandbox Code Playgroud)

返回.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);
Run Code Online (Sandbox Code Playgroud)

演示: https : //codesandbox.io/s/ywmvp95wpj

请记住,通过使用history您的用户可以离开,因为history.goBack()可以在打开您的应用程序之前加载访问者访问过的页面。


为了防止上述情况,我创建了一个简单的库react-router-last-location来监视用户的最后位置。

使用非常简单。首先,您需要安装react-router-domreact-router-last-locationnpm.

npm install react-router-dom react-router-last-location --save
Run Code Online (Sandbox Code Playgroud)

然后使用LastLocationProvider如下:

应用程序.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"));
Run Code Online (Sandbox Code Playgroud)

返回.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);
Run Code Online (Sandbox Code Playgroud)

演示: https : //codesandbox.io/s/727nqm99jj


for*_*d04 7

反应路由器 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>
    </>
  );
}
Run Code Online (Sandbox Code Playgroud)

代码沙盒示例

后退/前进多个历史堆栈条目:
<button onClick={() => navigate(-2)}>go two back</button>
<button onClick={() => navigate(2)}>go two forward</button>
Run Code Online (Sandbox Code Playgroud) 前往具体路线:
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
Run Code Online (Sandbox Code Playgroud)

useNavigate 替换 useHistory以更好地支持即将到来的 React Suspense/Concurrent 模式。


iku*_*iku 7

react-router-dom在v6上

import { useNavigate } from 'react-router-dom';

function goBack() {
  const navigate = useNavigate();

  return <button onClick={() => navigate(-1)}>go back</button>
}
Run Code Online (Sandbox Code Playgroud)


小智 5

this.props.history.goBack();

这适用于浏览器和哈希历史记录。


van*_*nts 5

对我有用的是在我的文件顶部导入 withRouter ;

import { withRouter } from 'react-router-dom'
Run Code Online (Sandbox Code Playgroud)

然后用它把导出的函数包装在我的文件底部;

export default withRouter(WebSitePageTitleComponent)
Run Code Online (Sandbox Code Playgroud)

然后允许我访问路由器的历史记录道具。完整示例代码如下!

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)
Run Code Online (Sandbox Code Playgroud)