简体   繁体   中英

How to prevent route change using react-router

There's a certain page in my React app that I would like to prevent the user from leaving if the form is dirty.

In my react-routes, I am using the onLeave prop like this:

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

And my onLeave is:

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

Is there a way to prevent the new route from firing and keep the user on the same page?

It is too late but according to the React Router Documentation you can use preventing transition with helping of <prompt> component.

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

if isBlocking equal to true it shows a message. for more information you can read the documentation.

I think the recommended approach has changed since Lazarev's answer, since his linked example is no longer currently in the examples folder. Instead, I think you should follow this example by defining:

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

And then define routerWillLeave to be a function that returns a string which will appear in a confirmation alert.

UPDATE

The previous link is now outdated and unavailable. In newer versions of React Router it appears there is a new component Prompt that can be used to cancel/control navigation. See this example

React-router api provides a Transition object for such cases, you can create a hook in a willTransitionTo lifecycle method of the component, you are using. Something like (code taken from react-router examples on the github):

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>
    );
  }
});

We're using React Router V5, and our site needed a custom prompt message to show up, and this medium article helped me understand how that was possible

TLDR: the <Prompt/> component from react-router-dom can accept a function as the message prop, and if that function returns true you'll continue in the navigation, and if false the navigation will be blocked

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM