Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

prevent POP actions to push the url into the history. #76

Merged
merged 2 commits into from
Oct 6, 2019

Conversation

lluistfc
Copy link
Contributor

When using your component with react (v16) + react-router (v4) and react-redux (v5) i've encontered an issue when doing a back from the browser.

If we start on page A and go to page B -> push event.
Once we are on page B we go to page C -> push event.
Once in page C we do a browser back, we end on page B -> pop event. but page B gets pushed onto history.
Back on page B we do a browser back, we end on page C

That behaviour is caused by:

if (pathnameInHistory !== pathnameInStore || searchInHistory !== searchInStore || hashInHistory !== hashInStore) {
  this.inTimeTravelling = true
  // Update history's location to match store's location
  props.history.push({
    pathname: pathnameInStore,
    search: searchInStore,
    hash: hashInStore,
  })
}

on ConnectedRouter.js#L38

By adding another condition to check if history action is "PUSH" i've managed to avoid this behaviour.

if (props.history.action === 'PUSH' && (pathnameInHistory !== pathnameInStore || searchInHistory !== searchInStore || hashInHistory !== hashInStore)) {

@supasate
Copy link
Owner

Thanks @lluistfc. Last time I looked into this and found some caveats. Sadly, I forget it now. Let me take a closer look into it again.

@lluistfc
Copy link
Contributor Author

Hello @supasate. Any news on this issue?

@vorlov
Copy link

vorlov commented Oct 25, 2018

pls check this asap, its a critical issue as the page is rendered twice on browser back action

@quoo
Copy link

quoo commented Oct 30, 2018

Any updates on this?

@supasate
Copy link
Owner

supasate commented Nov 4, 2018

Just revisited this issue.

I'm not sure that this fix is addressing general cases of clicking back button or only during the time traveling.

In the case of clicking the browser back button outside of time traveling, I cannot reproduce this behavior -> "Once in page C we do a browser back, we end on page B -> pop event. but page B gets pushed onto history."

From the codebase, page B will be pushed again only if it's in time traveling, i.e. the location in history and the location in redux store are different. By clicking back outside of time traveling, both locations are synced.

@supasate
Copy link
Owner

supasate commented Nov 4, 2018

@vorlov the page is rendered twice is a separate issue and this PR doesn't fix that. Let discuss in #141.

@pcs2112
Copy link

pcs2112 commented Dec 29, 2018

Critical issue. @lluistfc update fixes navigation issues using the browser's back button.

@reallistic
Copy link

reallistic commented Jan 14, 2019

Here is a (hopefully) a full explanation of what is going on with the code in question:

When using the redux dev tools to "time travel" (I.e. replay previous versions of your state) the browser history can become out of sync. The original code was designed to remedy this via the following intended logic:

  • Developer is on Page B.
  • Developer uses redux time travel to revert state to a point when Page A was active.
  • ConnectedRouter.js detects the mismatch of router state (changed) and history state (unchanged).
  • Page A is pushed onto window stack.

However, the unintended consequence is the following:

  • User is on Page B.
  • User hits the browser back button to go back to Page A.
  • A component mount on Page A fires an action that causes state to change.
  • ConnectedRouter.js detects the mismatch of router state (unchanged) and history state (updated to be Page A).
  • Page B is pushed onto window stack.
  • The LOCATION_CHANGED event fires due to the history listener POP'ing to Page A.
  • The router reducer updates the store.
  • ConnectedRouter.js detects the mismatch of router state (updated to Page A) and history state (on Page B).
  • Page A is pushed onto window stack.

@siddhant91
Copy link

@supasate @lluistfc Is there any update on when this will be merged and published.

@lluistfc
Copy link
Contributor Author

lluistfc commented Feb 4, 2019

@siddhant91 I'm sorry but we depend on @supasate to approve and accept the PR. I've been using the fork I made with my modifications with no issues. I haven't updated it since the modifications I made so it's really outdaded respect this version, give it a try if you want or fork current version and apply that modification.
Sorry I can't be of more help.

@ymaz
Copy link

ymaz commented Feb 27, 2019

any updates on that?

@@ -35,7 +35,7 @@ const createConnectedRouter = (structure) => {
} = props.history.location

// If we do time travelling, the location in store is changed but location in history is not changed
if (pathnameInHistory !== pathnameInStore || searchInHistory !== searchInStore || hashInHistory !== hashInStore) {
if (props.history.action === 'PUSH' && (pathnameInHistory !== pathnameInStore || searchInHistory !== searchInStore || hashInHistory !== hashInStore)) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to have here some detailed comment to explain why it is important to check the action.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we test it to be sure it wont break the next time?

@pybuche
Copy link

pybuche commented Mar 30, 2019

Hi ! Any updates on that ?

@JesusADS
Copy link

can anyone with permissions fix the .gitignore conflict?

@jwineman
Copy link

@jancama2 if I PR this same fix with tests and no .gitignore changes would you accept it?

@roryp2
Copy link

roryp2 commented May 7, 2019

Is this going to be updated and merged? This fixes #262

@jarommadsen
Copy link

This also fixes #349.

@supasate
Copy link
Owner

supasate commented Oct 6, 2019

Sorry all for keeping this PR for a long time! TBH, I still don't have time to think about it thoroughly, but, it seems to fix many issues listed above. So, I'm merging it first. If anyone finds issues after merging, please let me know!

@supasate supasate merged commit d3ca80a into supasate:master Oct 6, 2019
@pybuche
Copy link

pybuche commented Nov 11, 2019

Great, thanks ! Do you know when this will be released?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.