Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Forcing a React-Router <Link> to load a page, even if we're already on that page

Tags:

react-router

Is there a way to force a React-Router <Link> to load a page from path, even when the current location is already that page? I can't seem to find any mention of this in the react-router documentations.

We have a page on a route for "apply" that loads up a landing page with a hero image, some explanatory text, etc., and an "apply for this program" button that swaps in content that acts as an application form. This all happens on the same "apply" route, because users should not be able to directly navigate to this form without first hitting the landing page.

However, when they have this form open, and they click on the apply link in the nav menu again, the entire page should reload as it would on first mount, getting them "back" (but really, forward) to the landing page again.

Instead, clicking the <Link> does nothing, because react-router sees we're already on the "apply" page, and so does not unmount the current page to then mount a different one.

Is there a way to force it to unmount the current page before then mounting the requested page, even if it's for the page users are supposedly already on? (via a <Link> property for instance?)

like image 992
Mike 'Pomax' Kamermans Avatar asked Aug 08 '16 22:08

Mike 'Pomax' Kamermans


People also ask

How do you force page reload in react?

location. reload(false); This method takes an optional parameter which by default is set to false. If set to true, the browser will do a complete page refresh from the server and not from the cached version of the page.

Does react router reload page?

react-router-dom allows us to navigate through different pages on our app with/without refreshing the entire component. By default, BrowserRouter in react-router-dom will not refresh the entire page.

What is forceRefresh in react router?

The forceRefresh prop is a Boolean prop, and when set to true , navigation to any route will result in a page refresh—instead of updating specific sections of the page, the entire page is reloaded: <BrowserRouter forceRefresh={true}> <Link to="/dashboard">Dashboard</Link></BrowserRouter>


2 Answers

A fix I used to solve my little need around this was to change the location that React-Router looks at. If it sees a location that we're already on (as in your example) it won't do anything, but by using a location object and changing that, rather than using a plain string path, React-Router will "navigate" to the new location, even if the path looks the same.

You can do this by setting a key that's different from the current key (similar to how React's render relies on key) with a state property that allows you to write clear code around what you wanted to do:

render() {   const linkTarget = {     pathname: "/page",     key: uuid(), // we could use Math.random, but that's not guaranteed unique.     state: {       applied: true     }   };    return (     ...     <Link to={linkTarget}>Page</Link>     ...   ); } 

Note that (confusingly) you tell the Link which values you need pass as a state object, but the link will pass those values on into the component as props. So don't make the mistake of trying to access this.state in the target component!

We can then check for this in the target component's componentDidUpdate like so:

componentDidUpdate(prevProps, prevState, snapshot) {   // Check to see if the "applied" flag got changed (NOT just "set")   if (this.props.location.state.applied && !prevProps.location.state.applied) {     // Do stuff here    } } 
like image 27
flash Avatar answered Sep 21 '22 08:09

flash


In the Route component, specify a random key.

<Route path={YOURPATH} render={(props) => <YourComp {...props} keyProp={someValue} key={randomGen()}/>} /> 

when react see a different key, they will trigger rerender.

like image 195
Peiti Li Avatar answered Sep 21 '22 08:09

Peiti Li