Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prompt is made when navigating within same route

For the use case when a page has an internal route, the prompt triggers even when navigating to an internal route where a prompt might not be necessary, see code example. Is there a way to disable the prompt when navigating to known safe routes?

import React, {Component} from 'react';
import {BrowserRouter, Route, Switch, Link, Prompt} from 'react-router-dom';

export default class App extends Component {
  render() {
    return (
      <BrowserRouter>
        <Switch>
          <Route component={About} path={"/about"}/>
          <Route component={Home} path={"/"}/>
        </Switch>
      </BrowserRouter>
    );
  }
}

class Home extends Component {
  constructor(props) {
    super(props);
    this.state = {input: 'hello?'}
  }

  render() {
    return (
      <div>
        <h1>Home</h1>
        <input value={this.state.input} 
          onChange={(e) => this.setState({input: e.target.value})}/><br />
        <Link to={"/info"}>More Info</Link><br />
        <Link to={"/about"}>About Page</Link><br />

        {/*Triggers even when going to /info which is unnecessary*/}
        <Prompt message="Move away?" when={this.state.input !== 'hello?'}/>
        <Route path={"/info"} component={Info}/>
      </div>
    );
  }
}

class About extends Component {
  render() {
    return (
      <h1>About page</h1>
    );
  }
}

class Info extends Component {
  render() {
    return (
      <p>Here be some more info</p>
    );
  }
}

In the example above, About is a different page and so should trigger when the input has changed, which it does correctly. But the /info route is an internal route for Home, so the prompt is unnecessary, the internal state of Home is preserved after navigation so nothing is lost.

The actual use case here is for a modal to be shown when the route is active, but that is mostly CSS stuff so I excluded it from the example.

like image 334
Karagoth Avatar asked May 05 '17 05:05

Karagoth


People also ask

How does prompt work react?

The prompt is triggered on the page change and also based on the when prop. The when prop is used to conditionally trigger the prompt. For instance, if the when prop is set to true , the prompt will be shown every time page navigates (from home route to other routes or navigate forward / back).

Which component of react router is used to prompt the user before navigating away from a page?

Note that this example makes use of the withRouter higher-order component introduced in v2. 4.0. Used to prompt the user before navigating away from a page. When your application enters a state that should prevent the user from navigating away (like a form is half-filled out), render a <Prompt> .

What is nested route?

To recap, nested routes allow you to, at the route level, have a parent component control the rendering of a child component. Twitter's /messages route is the perfect example of this. With React Router, you have two options for creating nested routes.


1 Answers

I think a callback function as a message prop is what are you looking for. You can try to give a callback function to Prompt's message prop. That callback will be called with an object as an argument which will have all the information about the next route.

This is what documentation says about it:

message: func

Will be called with the next location and action the user is attempting to navigate to. Return a string to show a prompt to the user or true to allow the transition.

The object has a pathname attribute which is the next path by checking it you can figure out if the path is safe. Here is what I'm talking about:

<Prompt message={(params) => 
        params.pathname == '/about' ? "Move away?" : true } />

And here is the pen with working code which I've created from your examples.

Hope it helps.

like image 150
sehrob Avatar answered Oct 13 '22 01:10

sehrob