react-router-v6: don't unmount previous routes - react-router

I would like a mobile app like experience where when you push a new route on the stack, you can pop from the stack and previous route's state is still there. This is especially helpful when you have text fields on the previous route.
Currently when I fill in text fields on one page, then navigate to a new route, then pop back with:
const navigate = useNavigate();
...
onClick={() => navigate(-1)}
The text field is cleared, presumably because the previous route's component unmounted. How can I prevent this?

Related

Can you keep search params in the url after going to another page?

New programmer here who is messing around with lots of stuff.
So, i have this article searching application.
There is an input, you write stuff and it shows you articles containing the term that you used. Then you can go back and forth between pages of articles.
/home/?term=&page=0
When i click one of the articles, it takes me to a summary page with, well, a summary of the said article.
/home/article
What i want to do is, being able to go back to the home page with the last search parameters still intact.
Think of it similar to how google doesn't take you to just plain google.com but instead to the last search page that you were in.
How can i do that?
Small edit: if there is a way to just go back to the last page(With search params intact) without needing to put it in the URL or something similar, that is similarly fine of course.
In React Router v6 you can use navigate(-1) as documented here: https://reactrouter.com/docs/en/v6/hooks/use-navigate
Example:
import { useNavigate } from "react-router-dom";
const MyComponent = () => {
let navigate = useNavigate();
const goBack = () => {
navigate(-1);
}
return <button onClick={() => goBack()}>Back</button>
}

How to implement back button in angular 9

I'm implementing a small project with only two UIs.
1-The first UI is called Home which contains paginated users list the home component.
2-The second UI is called user details which contains user profile the user-details component
3- and of course the app component which contains the tool bar and router-outlet
let us suppose the following scenario
I'm in the home UI and in the second page of the paginated users list and I clicked on one of the users item then the user-details UI appeard and I'm now in the second UI and I now I want to navigate back to the home but when doing so the home UI is recreated and become the first page of the users list instead of the second page where we left it because this is my code of the back button
<img
routerLink = "/home" style="cursor: pointer;"
width="40"
alt="Angular Logo"
/>
<span routerLink = "/home" style="cursor: pointer;">Users</span>
my question is:
is there is any way to implement it in such a way it doesn't recreate the home page i.e. implement the correct behavior of back button?
There's a couple ways that you can approach this.
If you're using a pagination library (such as ngx-pagination), then hopefully the pagination component takes an input for the current page. You'd then need to keep track of that page either through a service or in persistent storage.
Whenever you route back to the Home UI, get the page that you were on and load that back into the pagination component.
Another way can be to use router parameters. By modifying your urls a bit, they can take on the following form:
/home/1
/home/2
/home/3
Clicking on a user in page 2 can give the url: /home/2/user-id (just an example)
The path for your home component can look like:
const routes: Routes = [
{ path: "home/:pageNumber", component: HomeComponent }
];
Upon loading the home component, you can get the get the router parameter as follows (I'm using the Router method but you can parse the URL manually as well):
export class HomeComponent implements OnInit {
constructor(private router: Router) {
const pageNumber = this.router.navigationExtras.params['pageNumber'];
}
}
You can then load this page number into your pagination component. Using this method doesn't require you to keep track of the previous pages.
There are probably better methods to do this, but this is just some suggestions :)

How to call browser back button in Angular Project

In my Angular 8 project, I currently have a landing page (template-table.component) that shows a list of items that can be filtered and sorted. The filter and sort are added to the route queryParams(ex: "/template-table?name=another&type=Type%201"). If you select an item in the list, you will be taken to another route (that has the template-details.component) that has more details on that item. This details page will have a 'back to list' button that should take the user back to their previous list page.
Since I want the user to be taken back to the list with the filter params they were previously using, I can't simply go to the route of that component, instead I want to go back in history (like how the browser back button works). So, how do I set an element to link to what the browser back button would be link to?
So, this is the bare minimum of my template-detail.component.html:
<h1>template-details works!</h1>
<div>{{template}}</div>
<div>{{id}}</div>
<div><a routerLink="/template-table/">Return to list page</a></div>
I think I also would like to check the route to see if it's the template-table component route with query params, and not an unrelated route. (So, the route would need to be like: "/template-table?params=xxx", and couldn't be "google.com". If the browser back button isn't related to the template-table, then it should go to "/template-table" without any params (or maybe my 404 page.)
The basic functionality that I'm wanting to achieve is for the user to be able to filter a list, go to another route with more info on a list item, and then return to the list with the same filters they previously added. If there would be a better way to do this than by trying to access the browser's back button, I'd love to hear about it.
Thank you for any assistance you can provide.
Arthurofos' suggestion to use the Location service seems to be relevant, as it can be used to navigate back to the view you were in prior to routing to a new component.
Of course, while there are very Javacsripty-ways to do these sort of things, it's always recommended to use Angular's libraries, if such an alternative exists.
In our case, it does, and it presents itself as the 'Location' service you can inject into your component.
import { Location } from '#angular/common';
#Component({
// Other component info
providers: [Location, {provide: LocationStrategy, useClass: PathLocationStrategy}]
})
export class TestComponent {
constructor(private location: Location, // Other constructor arguments) { }
public goBack() {
this.location.back()
}
}
https://alligator.io/angular/location-service/
Something like that should work:
routerLink="../"
But you can solve this problem in an elegant way thanks to the location of the library. Check out this post: enter link description here

Storing selected tab for restoration using React Redux and Router

Currently I have a sample which I'm working on which is a basic master details page. This sample uses react-router-redux. Within the details panel I have a number of tabs which use can see different facets of the selected item... all fairly standard stuff.
When the user selects an item from the master list, the URL that the clicked <Link ... /> send them to is something like customer/123. Within the route that is registered for that url (i.e. :id), I have an indexRoute route which replacess the route to default route/tab /customer/${nextState.params.id}/address.
All this works well and the user can navigate between tabs just fine. The problem comes when the user closes the detail window and selects a different detail. As expected, it opens the tab based on the route specified by the indexRoute. Under normal circumstances, this might be fine but I want it to remember which route was selected. I'm wondering if anyone has ideas on how this should be done?
I think I can do achieve this by registering a callback with the onClick event of the Link and dispatching an event which will result in key of the selected tab being saved in the store. Then within the onEnter of the indexRoute I can access the store and pull out this saved state and target the replace to this that item.
This should work but seems like a lot, just wondering if this seems right to other?
I would use the same approach - dispatch an action when the tab is clicked and store the tab key in the store.
Use mapStateToProps to retrieve the value.

React Router - change url without navigation

I have a new product page with the url /product/0. When product is saved using a button, I want to show 'Saved Successfully' message and change url to /product/1024 without actually navigating to that page as this would cause GET requests for the product and other data on the page.
I tried the Navigation mixin, however both, the transitionTo and replaceWith actually cause componentWillReceiveProps and I can't figure out a way how to distinguish my case (when all data on the page is already relevant) from navigation between different products, when data has to be reloaded.
So basically I am looking for a way to just change the url with React Router.
In a SPA there's no navigating to another page, the history change could lead to a different route being rendered, but as per your example, the same route will be rendered, so the only thing that did happen is a state change of the props of the Route component.
So you need to check this state with the previous state in componentWillReceiveProps and see if you need to refetch the data.