React Router - change url without navigation - react-router

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.

Related

React history - is there a way to remove duplicate entires when going back?

Currently for my back button I'm using window.history.back() which, in itself is working properly. My issue is with an iframe that I have for refreshing sessions, example
<iframe src="https://example.com/some/path?gcp-iap-mode=SESSION_REFRESHER" style="width:0;height:0;border:0; border:none;"></iframe>
Path in my project represents current url, so it keeps changing every time I change locations. Now, with the source the iframe has, it keeps throwing 404 and getting into my history so instead of clicking back button once, I have to do it at least two times - first times it fails as it tries to reach randompath?gcp-iap-mode=SESSION_REFRESHER and then it goes to proper path.
My question is, is there a way for me to check the "back" value, to see if the "back" value has a specific query (for example gcp-iap-mode part), or check if it's the same as a current location (duplicate) so I can skip that entry (and couple of back steps) and go back to a different path in history stack?
Seems an issue like this is common in iframes. I tried looking at it from a wrong perspective, by looking for ways to change history where the only thing that needed to be changed is the iframe itself.
Basically when we only change the src attribute of the iframe it gets rendered again and again and the src gets pushed to history stack. What we needed here was the iframe to unmount and the soultion to all of that was pretty simple - add a key prop to the iframe.
This is a blog page that helped me, so if somebody wants to read more:
https://www.aleksandrhovhannisyan.com/blog/react-iframes-back-navigation-bug/

Can HTTP GET be used if there are small side-effects?

As far as I understand, GET has to be idempotent - it cannot change anything in the system and repeating it should always return the same unless something else changed the state of the application.
Problem is, on my website, there should be a lot of little changes based on whether some content has been already seen before by the user. I mean, like notifications, new message alerts, content sorting based on whether user saw it or not, how many users saw the content counters... For example when user clicks on notification, the notification should disappear from his notification panel and never be seen there again, so it changes something - state of the notification, but I can press F5 as many times as I want and it always returns the same page with same info, same buttons etc.
Can I ignore this kind of side-effect as too small and I can use GET or do I have to make most links and buttons on the website use POST like I do with links and buttons which lead to more "serious" changes? I do that by making forms around each of them with those links as form actions and original buttons as submit buttons of the form which seems a little messy to me and I don't want it almost everywhere (or is there a better way?).
This can be tackled from several points of view, I'll illuminate it from this angle:
The end result here is always the same, hence the request is idempotent.
The user visits the URL, the end result is that the notifications are cleared. They can visit the page again and again, the end result is that the notifications are cleared. They're not going to get an error message because the notifications have been previously cleared (that would not be idempotent). Yes, they will see different content each time they visit the page, but nothing says that the page content must be identical each time the resource is requested (that would put half the web in a bind).
Contrast that with a POST request to /questions (which creates a new question, for example): each time you repeat that POST request, a completely new resource is being created. You POST once, and /questions/12345 is being created. You repeat the same request, /questions/12346 is being created. That is not idempotent.
No, you do not need to make all those requests into POST requests.

Polymer: How to implement navigations

The way I currently implemented navigation in my Polymer 1 application is this:
I use paper-menu and paper-submenu
on iron-select, I will create a route based on the names of the paper-item
for example groups, example, test will be concatinated into a route like: /groups/example/test. User when then be routed there using this.set('route.path', '/groups/example/test')
Also, on page load, to highlight the correct menu items, I parse the URL and selected the correct menu items. So far so good.
The problem here is: suppose I have even further nesting like /groups/example/test/subpage1/subsubpage2. When the user navigates to such a URL, he is forced back to /groups/example/test because the parsing of URL to select the correct items.
The workaround I have currently is: instead of attaching on-iron-select I will setTimeout then attach this handler. This is so that the user does not get forced back to the wrong page, but this feels wrong. Whats the correct way of doing this?

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.

How to use pushState,replaceState and popState correctly?

I'm trying to use the history API but I can't get it working as I'd expect. I've look at several examples but they all appear to be doing something wrong. That is, this flow doesn't work as expected:
On new page call pushState
On popState load desired page
What I'm finding happens is that for #2 the URL is not modified to the old state (testing in Firefox). Unless I call pushState, or replaceState again the URL stays where it was. I'm also finding that somehow the first page ends up duplicated in the browser's history (holding down back I can see it).
How exactly should the history be used so that Back/Forward/Reload all work like a traditional page flow?
The problems I'm having relate to the use of an iframe in the page. Each change of the location of the frame creates a new history entry which messages with the desired history. To prevent this one must replace the iframe location instead of assigning a new one.
document.getElementById('content_frame').contentWindow.location.replace( new_path )
Location.replace doesn't create a history entry.