Skip to content

Prevent pushing duplicate paths to the history API.#558

Closed
guidobouman wants to merge 9 commits into
remix-run:masterfrom
guidobouman:patch-1
Closed

Prevent pushing duplicate paths to the history API.#558
guidobouman wants to merge 9 commits into
remix-run:masterfrom
guidobouman:patch-1

Conversation

@guidobouman

@guidobouman guidobouman commented Jan 11, 2018

Copy link
Copy Markdown
Contributor

Fixes #507

@guidobouman

Copy link
Copy Markdown
Contributor Author

Okay, this is a little bigger...

HashHistory emits a warning about replacing instead of pushing to the stack. But this is actually the WHATWG standards behaviour. So should I remove the warning from the HashHistory and homogenise the implementation around BrowserHistory, MemoryHistory & HashHistory?

Comment thread modules/createBrowserHistory.js Outdated
const action = "PUSH"
const location = createLocation(path, state, createKey(), history.location)

if (createPath(location) === createPath(history.location)) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You're only comparing the pathname in this case. What about the search/querystring? Since you're doing this in multiple histories, you should export a common function, like locationsAreEqual.

@guidobouman guidobouman Jan 11, 2018

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Great tip, thanks.

There's already a locationsAreEqual method, which is great. But it also checks for key, something we don't want. Should I add an override to the method?

That would result in the following signature:

locationsAreEqual = (a, b, ignoreKey) => { ... }

Sounds reasonable if you ask me. On the other hand, invoking the function gets a bit vague that way:

locationsAreEqual(location, oldLocation, true)

I could also create a new method locationsExceptKeyAreEqual or locationEqualsDestination. What do you think?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hmm, I'm not sure why key is in there at all. If the key is equal, the locations are equal. That's the point of the key value being in there. So, that function would appear to be fundamentally flawed. There's only one internal usage:

https://github.com/ReactTraining/history/blob/dca21eaa9230ae187c72ef657f70aac97cb172aa/modules/createHashHistory.js#L110

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Oh, I see why. Hash histories don't use key. I haven't been following those specifics too carefully, since I don't use those myself.

I would add a locationsAreEquivalent function in this case that checks pathname and search are equal.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks for thinking along!

Looks like the key prop could be removed from the compare function, right? As hash history doesn't use the key prop anyhow. Then it would be usable in all places without adding an extra method.

@guidobouman
guidobouman force-pushed the patch-1 branch 3 times, most recently from 0796a45 to e3206fb Compare January 11, 2018 18:10
@guidobouman

Copy link
Copy Markdown
Contributor Author

Rewrote history a little. Not too smart for open-source, oops.

@guidobouman

Copy link
Copy Markdown
Contributor Author

I see that semi-colons have been enabled in Prettier, I'll fix the conflicts.

@guidobouman

Copy link
Copy Markdown
Contributor Author

Waiting for #559 before I can fix the conflicts in this branch.

@guidobouman

Copy link
Copy Markdown
Contributor Author

@timdorr Ready for review again!

PS: What about the HashHistory warning?

@loganpowell

Copy link
Copy Markdown

subscribing to this as mentioned in #507 (comment)

@mjackson

Copy link
Copy Markdown
Member

HashHistory emits a warning about replacing instead of pushing to the stack. But this is actually the WHATWG standards behaviour.

What do you mean @guidobouman? It's not possible to push the same path using hash history the way it is currently implemented.

screen shot 2018-01-18 at 9 08 19 pm

Notice how the second window.location.hash = '/home' does not increase window.history.length. This means that pushing the same path using hash history does not create a new entry in the browser's history stack.

@mjackson

Copy link
Copy Markdown
Member

I should also note that using pushState does push a new entry onto the history stack, even if the paths are the same.

screen shot 2018-01-18 at 9 12 25 pm

If I understand you correctly, @guidobouman, are you saying it shouldn't?

@timdorr

timdorr commented Jan 19, 2018

Copy link
Copy Markdown
Member

Perhaps we should fix this higher up in React Router's <Link> component? It's ultimately to fix a behavior to match <a> more closely.

@guidobouman

Copy link
Copy Markdown
Contributor Author

Moving the discussion on this to #470, there's more historical info there.

@mjackson

Copy link
Copy Markdown
Member

Based on the discussion in #470 I don't think we want to change the behavior of push since pushState does in fact push a new URL onto the history stack. Instead, the proposal is to add a new history.link API that behaves more like clicking on a link would do.

I'm going to close this PR, but thank you for taking the time to push this discussion forward @guidobouman :)

@mjackson mjackson closed this Jan 21, 2018
@guidobouman

guidobouman commented Jan 21, 2018

Copy link
Copy Markdown
Contributor Author

Always, @mjackson!

PS: I added some small bug fixes / tweaks in this PR, I'll put them up as different PR's.

@guidobouman
guidobouman deleted the patch-1 branch January 21, 2018 21:06
@lock lock Bot locked as resolved and limited conversation to collaborators Jun 4, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants