在 react-router 2 中禁用后退按钮

disable back button in react-router 2

我正在使用 react-router 2。我的路由定义为

   <Route path="/" component={App}>
       <IndexRoute component={Home}/>
       <Route path="/about" component={About}/>
       <Route path="/login" component={Login} onEnter={redirectToDashboard}/>
       <Route path="/logout" component={Logout} onEnter={logoutSession}/>
       <Route path="/dashboard" component={Dashboard} onEnter={redirectToLogin}/>
   </Route>

一切正常,但我在从仪表板页面禁用后退按钮时遇到问题。

成功登录后,我将用户重定向到仪表板页面,但是当用户单击后退按钮时,它会再次进入登录页面。当用户在仪表板页面时,我想禁用 browser 的后退按钮。

无法禁用浏览器按钮。 我的建议是,如果 he/she 已记录

,则将用户重定向回仪表板页面

实际上您无法禁用 后退 按钮。您可以通过阻止浏览器的“back”操作来使用 hack。只需将一些代码添加到您的 Dashboard 组件 compnentWillMount() 生命周期方法即可触发浏览器的“forward”操作:

componentWillMount() {
   setTimeout(() => {
     window.history.forward()
   }, 0)
   window.onunload=function(){null};
}

但最有可能更好的解决方案是根据用户登录状态进行一些重定向。

你最好的选择是当用户登录时他/她被重定向到仪表板。如果出于某种原因用户点击后退按钮你应该:

如果用户已登录 留在页面仪表板上

if(logged) {
  history.pushState(null, null, location.href);
  window.onpopstate = function(event) {
    history.go(1);
  };
}

将无法返回。

在您要禁用返回的页面上(例如,在 LoginApp 上)添加此块,以禁用网络历史记录返回

componentDidMount() {
    window.history.pushState(null, document.title, window.location.href);
    window.addEventListener('popstate', function (event){
        window.history.pushState(null, document.title,  window.location.href);
    });
}

应用所有这些技巧,URL 暂时变为 login,然后变为 wherever-we-push。 相反,我们可以做的是:在登录中,api 端点 returns 成功,执行:

history.replace('/Whatever_screen')

这将从 window.history 堆栈中删除登录屏幕,并且屏幕不会闪烁。

在您的登录屏幕中添加替换到 /dashboard

import React, { Component } from 'react';
import { withRouter } from 'react-router-dom'
import createBrowserHistory from 'history/createBrowserHistory'
const history = createBrowserHistory()

class LoginPage extends Component {
    componentDidMount(){
        history.replace({ pathname: '/dashboard' })
    }
    render() {
        const { history } = this.props
        return (
            <div>
            <h1>Login Page</h1>
            <button onClick={() => {
              login().then(() => {
                history.push('/dashboard')
              })
            }}>Login</button>
          </div>
        );
    }
}

export default withRouter(LoginPage);

原因是将您当前的路径 (/login) 替换为 /dashboard。在添加之前,请确保您正确设置了身份验证。

为了提高代码的可重用性,我们可以在我们的 index.html 中添加一个事件侦听器,并从我们所有的 componentDidMount() 方法中调度浏览器返回禁用事件。

index.html,

window.addEventListener('navigationhandler', function (e) {
  window.history.pushState(null, document.title, window.location.href);
  window.addEventListener('popstate', function (event) {
    window.history.pushState(null, document.title, window.location.href);
  });
});

在 React componentDidMount() 方法中,

componentDidMount() {
   window.dispatchEvent(new CustomEvent("navigationhandler"));
}

无法禁用浏览器按钮。但是我们可以使用 listen()go()push() 等历史方法来覆盖 react.js 中后退按钮的默认行为。也尝试使用 withRouter().

以下是执行此操作的示例代码。请查看 componentDidMount()componenetDidUnmount() 方法。

import React from "react";
import { Redirect, Switch, Route, withRouter } from "react-router";

import Page1 from "./Page1";
import Page2 from "./Page2";
import Page3 from "./Page3";

class App extends React.Component {
  constructor(props) {
    super(props);

    // Store the previous pathname and search strings
    this.currentPathname = null;
    this.currentSearch = null;
  }

  componentDidMount() {
    const { history } = this.props;

    history.listen((newLocation, action) => {
      if (action === "PUSH") {
        if (
          newLocation.pathname !== this.currentPathname ||
          newLocation.search !== this.currentSearch
        ) {
          this.currentPathname = newLocation.pathname;
          this.currentSearch = newLocation.search;

          history.push({
            pathname: newLocation.pathname,
            search: newLocation.search
          });
        }
      } else {
        history.go(1);
      }
    });
  }

  componentWillUnmount() {
    window.onpopstate = null;
  }

  render() {
    return (
      <Switch>
        <Route exact path="/" render={() => <Redirect to="/page1" />} />
        <Route path="/page1" component={Page1} />
        <Route path="/page2" component={Page2} />
        <Route path="/page3" component={Page3} />
      </Switch>
    );
  }
}

export default withRouter(App);

更多:Disable react back button