Closed oferitz closed 6 years ago
No it's not.
In electron you can use a memory history instead of hash, yeah?
import {
createMemorySource,
createHistory,
LocationProvider
} from "@reach/router"
let source = createMemorySource("/starting/url")
let history = createHistory(source)
let App = () => (
<LocationProvider history={history}>
<Router>
{/* ... */}
</Router>
</LocationProvider>
)
Thanks.
The memory history will probably work, but would you consider a PR that add support for hash history also?
No. Hash history has a lot of edge cases that I don't want to deal with, but if you look at the source of createMemorySource
you can see what you need to make a createHashSource
.
@oferitz I'd quite like this too. If you work on a Reach add-on to support hash history, do you mind posting it here so others may use it too?
And thanks Ryan for providing this router. It's definitely the easiest to use to-date.
@will-stone If i understood @ryanflorence correctly, he will not consider any PR for adding hash support. so i didn't started any work on such thing. i actually found that memory history could work on my use case (Electron).
Okay, thanks @oferitz, I'll look into it myself if I get time.
@oferitz I've had a go at creating my own hash source: https://github.com/will-stone/hash-source
@ryanflorence I know you said you wouldn't be officially supporting this but I'd really appreciate it if you could do a quick once-over of the code (there's not a lot there) and let me know if there's any glaring omissions, or is just not the way it should be handled. Thanks.
Wow, you can use the same LocationProvider with a different history source? This looks very promising, thanks @will-stone. Please ping me when it's published or if you need any help.
@nickcolley it has been published: https://www.npmjs.com/package/hash-source
I've put together a sandbox to demo it: https://codesandbox.io/s/30yj1213m However, the back/forwards functionality doesn't work on the sandbox (it did on my local tests). Which means we may need to use onHashChange. Anyway, if anybody would like to help out, please log issues/PRs on its repo and save Ryan from the noise on here.
edit: loading in separate window demonstrates it properly: https://30yj1213m.codesandbox.io/#/
Yeah @will-stone I was doing some things with hash previously and recall codesandbox not liking it.
I also write a lib for use reach/router with hash. and also publish it look the similar to @will-stone . I think the reach/router just use a little part of location api and history api, so create a hash histroy is easy. I will update it continuously feel free to add issue
https://github.com/j3l11234/reach-router-hash-history https://www.npmjs.com/package/reach-router-hash-history
@j3l11234 Hmmm... I'm not sure how I feel about that. Does yours offer anything over mine? It looks very similar. Some comments and functions are identical! If anything is missing, I'm happy to accept PRs and issues. It's not even forked or credited in the README. I'd say you've scored badly on open source etiquette.
@ryanflorence - I don't think createMemorySource
persists state across refreshes which can be annoying during development. Would appreciate if memory is preserved across page refreshes.
FYI. This will not be a problem for hash routers or browser routers as the href
on refresh won't change.
One workaround I could think of -
const REACH_ROUTER_LOCATION = "<SOME_STORAGE_KEY>";
const path = localStorage.getItem(REACH_ROUTER_LOCATION);
let source = createMemorySource(path || "/");
let history = createHistory(source);
const RootReachNode = () => (
// You could also use a useEffect/unmount hook to capture pathname if this is not root node
<LocationProvider history={history}>
{...}
</LocationProvider>
);
window.addEventListener("beforeunload", () => {
localStorage.setItem(REACH_ROUTER_LOCATION, history.location.pathname);
});
@will-stone Im sorry about that,In fact, that was not my intention. you can find the previous commit. I use another way to fix it. I want to make hash history similar to history, such as the overide addEventListener, I rewrite popstate to hashchange. I will simulate the state like history later. I will add the credit for you and I sincerely apologize for that again.
@will-stone thanks! Works fine for my use case.
I created a forked version for my use case https://github.com/gaoxiaoliangz/router. Just add useHashRouting
to the Router component and you are good to go.
One rookie question though. If reach router is not using hash to prevent page reload how you supposed to keep redux state?
Isn't the idea of react to create single page web applications so that you do not have to reload everything on each page change? If we are reloading everything when changing page what is the purpose of the react than I can use jQuery as well.
The HTML5 History API (specifically History.pushState()
) allows you to change the URL without reloading, as if the user navigated normally. Most routing libraries including Reach Router use this to simulate navigation in SPAs without full reloads. Hash history is just an alternate URL syntax for browsers that don't support HTML5 History.
Yeah, that is true. Except when user wants to change route manually than page is reloaded. For example if I am on route example.com/#home and I change url in the address bar to example.com/#report the page will not be reloaded. But if you do not use hash and change url in the address bar the page will reload.
@will-stone Hey will, this hash history is working great, but how can I use navigate function with it?
If I use navigate it stops using hash completely and it just redirects like regular link.
The HTML5 History API (specifically
History.pushState()
) allows you to change the URL without reloading, as if the user navigated normally. Most routing libraries including Reach Router use this to simulate navigation in SPAs without full reloads. Hash history is just an alternate URL syntax for browsers that don't support HTML5 History.
But everytime I use navigate function or Link component the page reloads completely and all state of the app is lost. How can I prevent this (without using hash history) ?
Hi @hardcoremore, thanks for the praise. Do you mind raising any issues you have with hash-source on the repo itself? If you include a codesandbox/demo-repo that would greatly help with debugging the issue.
Hi will, yes I will open the ticket on the repo.
Thanks
@hardcoremore Hi, have you found the solution to this? It will be a great help if you could share your findings, thanks!
But everytime I use navigate function or Link component the page reloads completely and all state of the app is lost. How can I prevent this (without using hash history) ?
@nickmccurdy
Hash history is just an alternate URL syntax for browsers that don't support HTML5 History.
You are not right, there is a huge difference between them. In case we have link without hash (some.site/about/
for example) after page refresh or reopen tab, or if you share that link - browser create GET request to some.site/about/index.html
. By default static server return 404 error on this request because entry point with js who handle routing located in some.site/index.html
.
Of course it can be fixed after some back-end reconfiguration for redirect requests, however, we have many cases when we do not have access to do this (surge.sh, github pages, netlify, etc.)
Hash routing does not require any additional configuration to work because some.site/#/about/
create correct request to some.site/index.html
@j3l11234 thx, your package help me
Most HTML5 Offline applications needs hash route, because you must list all of your paths in the app.manifest
resource.
I am in the situation that @Akiyamka outlines; I use static hosting, need my users to be able to open mysite.com/img/[image_id] in a new tab, and there's no way to do this AFAIK without using react-router or SSRing all 1m of my images.
Please consider making it easier to use this, I use GitHub Pages on all my open source project sites and it's significantly more difficult to set up Reach Router with hash routing than to use another router that supports it, but I need Reach Router's accessibility features
I tried to use solutions provided here and as well as the package reach-router-hash-history
. I couldn't use navigate()
function because state wasn't propagated with the hash history.
I have rewrite hash history code and made a gist that fixes the problem. I am putting it here if anybody needs it.
https://gist.github.com/prionkor/59215ff78de7b706fbb6b97a9a61b578
FYI almost a year has passed since my last comment. From what I remember, Reach Router's development has slowed down and new features will likely not be added. Instead, it's recommended to migrate to React Router 6, which is based on some of the API improvements of Reach Router. It also has a HashRouter
component built in.
In React router you can do something like this:
Is this supported?
This is very useful in environment like Electron where you can't use the "normal" HTML5 history API.
I didn't found anything in the docs except from this: https://reach.tech/router/api/createHistory but it doesn't seems related to what i'm looking for.