【问题标题】:How to prevent route change using react-router如何使用 react-router 防止路由更改
【发布时间】:2016-09-05 20:06:08
【问题描述】:

我的 React 应用中有一个页面,如果表单脏了,我想阻止用户离开。

在我的 react-routes 中,我正在使用这样的 onLeave 道具:

<Route path="dependent" component={DependentDetails} onLeave={checkForm}/>

而我的onLeave 是:

const checkForm = (nextState, replace, cb) => {
  if (form.IsDirty) {
    console.log('Leaving so soon?');
    // I would like to stay on the same page somehow...
  }
};

有没有办法阻止新路由触发并使用户保持在同一页面上?

【问题讨论】:

  • 你用的是什么版本?
  • 嗨@PhilVarg,我正在使用react-router@2.0.1 和react-router-redux@4.0.2

标签: reactjs react-router


【解决方案1】:

我们正在使用 React Router V5,我们的网站需要显示自定义提示消息,this medium article 帮助我了解了这是如何实现的

TLDR:来自 react-router-dom 的 &lt;Prompt/&gt; 组件可以接受一个函数作为消息道具,如果该函数返回 true 你将继续导航,如果 false 导航将是被屏蔽了

【讨论】:

    【解决方案2】:

    我认为自拉扎列夫的回答以来推荐的方法已经改变,因为他的链接示例当前不再位于 examples 文件夹中。相反,我认为您应该遵循this example 的定义:

    componentWillMount() {
      this.props.router.setRouteLeaveHook(
        this.props.route,
        this.routerWillLeave
      )
    },
    

    然后将routerWillLeave 定义为一个返回字符串的函数,该字符串将出现在确认警报中。

    更新

    之前的链接现已过时且不可用。在较新版本的 React Router 中,似乎有一个新组件 Prompt 可用于取消/控制导航。见this example

    【讨论】:

    【解决方案3】:

    为时已晚,但根据React Router Documentation,您可以在&lt;prompt&gt; 组件的帮助下使用preventing transition

      <Prompt
          when={isBlocking}
          message={location =>
            `Are you sure you want to go to ${location.pathname}`
          }
        />
    

    如果isBlocking 等于true,它会显示一条消息。有关更多信息,您可以阅读文档。

    【讨论】:

    • @vsync docs 不是在守卫后面有条件地渲染 ,您可以始终渲染它,但通过 when={true} 或 when={false} 相应地阻止或允许导航。
    • message 属性也可以是一个返回 true 或 false 的函数,而不仅仅是一个字符串。这可以帮助避免浏览器警报,转而使用自定义模式或其他东西
    【解决方案4】:

    React-router api 为这种情况提供了一个Transition 对象,您可以在您正在使用的组件的willTransitionTo 生命周期方法中创建一个钩子。类似的东西(代码取自 github 上的 react-router examples):

    var Form = React.createClass({
    
      mixins: [ Router.Navigation ],
    
      statics: {
        willTransitionFrom: function (transition, element) {
          if (element.refs.userInput.getDOMNode().value !== '') {
            if (!confirm('You have unsaved information, are you sure you want to leave this page?')) {
              transition.abort();
            }
          }
        }
      },
    
      handleSubmit: function (event) {
        event.preventDefault();
        this.refs.userInput.getDOMNode().value = '';
        this.transitionTo('/');
      },
    
      render: function () {
        return (
          <div>
            <form onSubmit={this.handleSubmit}>
              <p>Click the dashboard link with text in the input.</p>
              <input type="text" ref="userInput" defaultValue="ohai" />
              <button type="submit">Go</button>
            </form>
          </div>
        );
      }
    });
    

    【讨论】:

    • 感谢 Lazarev,但在我的代码示例中,有没有办法只“停留在页面上”而不去选定的路线?
    • 您不会从路由页面执行此操作,而是从您的组件执行此操作,添加一个 willTransitionFrom 钩子,并从那里调用 transition.abort() 检查您的表单是否脏跨度>
    • 我认为你做不到。即使可以,这似乎也是一种不好的方法,因为甚至没有任何参数传递给onLeave 事件。如果我没记错的话,onLeave 最常用于动画。顺便问一下你要怎么访问form
    猜你喜欢
    • 1970-01-01
    • 2021-11-16
    • 2019-11-02
    • 2021-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多