react-router: Link to={locationObject} has inconsistent behavior between search and hash.
Version
5.0.0
Test Case
https://codesandbox.io/s/wyxq313458
Expected Behavior
Based on the comments on #6713, I expect that <Link to={{ hash: "hash"}}/> and <Link to ={{ search: "search"}}/> behave the same, in that they link to the basename of the router. Or that both link to the current location + hash / search.
Especially noteworthy is the difference between { search: "search"} - which just appends the search - and { hash: "hash", search: "search"} which links to basename + hash + search.
I’d also expect that after navigating with such a Link, that the URL I see in the browser is reflected in the routing. But that isn’t the case.
Actual Behavior
Part 1: Link targets
Given the basename “root” and the current location “path”:
| “to” prop | target url |
|---|---|
{hash: "hash"} |
/root#hash |
"#hash" |
/root/path#hash |
{search: "search"} |
/root/path?search |
"?search" |
/root/path?search |
{search: "search", hash: "hash"} |
/root#hash?search |
Consistent would be:
| “to” prop | target url |
|---|---|
{hash: "hash"} |
/root#hash |
"#hash" |
/root/path#hash |
{search: "search"} |
/root?search |
"?search" |
/root/path?search |
"#hash?search" |
/root/path#hash?search |
{search: "search", hash: "hash"} |
/root#hash?search |
Part 2: Routing
When clicking on a Link without a pathname specified, the user is navigated to the baseName / root URL. But the Router still matches the prior path. You can test that in the above sandbox by clicking on the “otherpath”, then clicking on the “HASH location object” link. It still matches and renders the OtherPath route.

Part 3: BrowserRouter vs. HashRouter
Edit: I just had the idea to check if the behavior is the same for different Routers. It’s not. MemoryRouter and BrowserRouter seem to behave the same, but HashRouter is different for { search: "search"}. Both in terms of target URLs (see below) and in that the location object sans pathname causes the expected route change based on the new URL.
| “to” prop | target url - browserRouter | target url hashRouter |
|---|---|---|
{hash: "hash"} |
/root#hash | #/root#hash |
"#hash" |
/root/path#hash | #/root/path#hash |
{search: "search"} |
/root/path?search | #/root?search |
"?search" |
/root/path?search | #/root/path?search |
"#hash?search" |
/root/path#hash?search | #/root/path#hash?search |
{search: "search", hash: "hash"} |
/root#hash?search | #/root/path#hash?search |
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 16 (16 by maintainers)
I appeneded differences between HashRouter and BrowserRouter.
I will take a closer look at it later. I think the source of both problems is the same and the solution for one will fix the other problem.