Some examples:
* there's no relative routes https://github.com/ReactTraining/react-router/issues/2172
* there's no way to refresh the page https://github.com/ReactTraining/react-router/issues/1982 ("that's your responsibility, not ours")
* The scroll position will stick when you navigate to a new route, causing you to need to create a custom component wrapper to manage scrolling https://github.com/ReactTraining/react-router/issues/3950
* React router's <Link> do not allow you to link outside of the current site https://github.com/ReactTraining/react-router/issues/1147 so you have to make an <a> in those cases. This doesn’t sound bad, but it’s particularly frustrating when dealing with dynamic or user generated content. Why can’t they handle this simple case?
* Navigating to the same page would not actually reload the page, it would just trigger a componentDidMount() on all components in the page again, which led me to have a lot of bugs when I did some initialization in my constructor
* Relative links are supported out of the box. If you use '..', it is relative to the current "directory" (i.e. it ignores any trailing slash)
* Navi allows you to reload the current route using `navigation.refresh()`. This is undocumented as I didn't realize that it is a feature people actually need, although I'd be happy to document it in a future release after making sure that the behavior makes sense.
* Navi handles scroll-to-hash and scroll-to-top automatically (and you can disable it by passing a prop)
* The <Link> component works for external links automatically.
* Navigating to the same page does not reload the page, but you could implement this by creating a wrapper around <Link>, and calling `navigation.refresh()` if the link points to the current page.
And while it's not specifically one of your pain points, Navi also works server-side and has an in-built static build tool for SEO – which is probably important given the features that you're looking for.
While it's easy to say "just don't do client-side routing", there are a growing number of sites where client-side routing makes sense. I saw that you're making a music site, and client-side routing definitely makes sense. I'm building content for teaching React/Frontend Dev, and the live editor loads a lot of files that should be cached between pages, so client side routing also makes sense (and besides, it's just so much faster).
Would love to hear any feedback on the tool :-) Here's the URL: https://frontarm.com/navi/en/
> React router's <Link> do not allow you to link outside of the current site
Both valid points. Not show stoppers though. And not enough to make me regret using the library. The solution to the external links issue is a one-liner.
> there's no way to refresh the page https://github.com/ReactTraining/react-router/issues/1982 ("that's your responsibility, not ours")
That is your responsibility. Why do you need the routing library to handle page refreshing for you?
> the scroll position will stick when you navigate to a new route
Making the page scroll to the top when navigating to a new page is trivial. I would 100% rather have this problem instead of the opposite: scroll jumping to the top when I don't want it to. That's so much harder to fix.
> Navigating to the same page would not actually reload the page, it would just trigger a componentDidMount() on all components in the page again, which led me to have a lot of bugs when I did some initialization in my constructor
That's exactly what it's supposed to do. It's a client side routing solution. (I'm also pretty sure that it doesn't remount)
From the issues that you've had with the library, it seems like client side routing is not actually what you're looking for. If you regret using it so much, may I ask what the alternative would be?
IMO a project either needs client side routing, or it doesn't. If it does, then React Router is the obvious choice. Otherwise, of course, don't use it and save yourself from unnecessary complexity.
It is most definitely not a one-liner.
> Making the page scroll to the top when navigating to a new page is trivial.
So do it for me. There’s no reason a routing library should break default behavior.
> That's exactly what it's supposed to do. It's a client side routing solution. (I'm also pretty sure that it doesn't remount)
Then it’s “supposed” to have inconsistent behavior. Navigating anywhere else in my site will call constructors to all my components. Navigating to the same page won’t.
> From the issues that you've had with the library, it seems like client side routing is not actually what you're looking for.
My site was a music site. I wanted clientside routing so I could keep music playing while you navigated between links. Seemed like a slam dunk for clientside routing to me.
> may I ask what the alternative would be?
Quite honestly I would go onto GitHub and look for any routing solution that didn’t have multiple closed unfixed issues with hundreds of thumbs up.
Ended up sticking through it as it appeared to be the default Router for React. It looks like there's some options now, so I'll consider moving if I have to suffer through another major breaking change.
I've been managing "relative" routes by just using `match.path` and `match.url` from the previous route. Works fine.
function Parent(props) {
return (
<>
<Link to='/child'>Child</Link>
<Route path='/child' component={Child}/>
</>
);
}
function Child({match}) {
return (
<>
<Link to={`${match.url}/grandchild`}>Grandchild</Link>
<Route path={`${match.path}/grandchild`} component={Grandchild} />
</>
)
}https://gist.github.com/tim-field/99104278abfad1b8dd94d26717...
I combine this with a simple switch statement in my main component and it does the job.
const [page, setPage] = useRouter('/')
*https://reactjs.org/docs/hooks-custom.html- has an easy <Router onChange={...}> callback
- instead of <Link to> you can just use <a href> and it works for internal and external links
- routes are per default "exact", so "/profile" doesn't match "/profile/settings"
So much better, highly recommended. You probably need to alias "preact" to "react" in your webpack settings though.
* Built-in focus management.
* Smaller library size.
* Implicit route matching that Just Works.
* More comprehensive docs with live examples.
Migration was easy. Highly recommended.
FWIW, I use Reach Router for everything now and greatly prefer it.
I'm now extremely happy with my new router of choice router5 (not to be confused with React Router 5) https://router5.js.org.
I wrote 2 articles about it in case it can help someone:
- https://www.vincentprouillet.com/blog/testing-a-different-sp...
- https://www.vincentprouillet.com/blog/testing-a-different-sp...
It probably changed a bit since those articles but I was happy with it. A very simple codebase using that can be seen on https://github.com/Keats/hn-react
I've had a look at react-router multiple times over the years, and the best thing going for them seems to have been that they managed to squat that generic name early on. From the docs and GitHub, it's always been abundantly clear that the "current version sucks, mistakes were made, next version will totally fix everything" again and again.
1. Having to write middleware for many things is quite hard for junior devs, as it requires deep understanding of how router works. (We have middleware for dependency injection, MobX per-page store, data fetching, auth check)
2. Due to the tree-based router design, some routes are impossible. See https://github.com/troch/route-node/issues/17 https://github.com/troch/route-node/issues/18
I still haven't found router of my choice yet. Maybe router5 without route-note could work for me, but I still wouldn't recommend it to any team.
Not only is router5's API simple, well-documented and easily programmable, the router5 folks have been receptive to feedback and pull requests. They also keep fairly well up-to-date compared to react-router (router5 supports React hooks, react-router doesn't yet).
I'm content with the direction and design of router5 and encourage others to check it out.
And used router5 for that.
Didn't even need that many hacks: https://gist.github.com/dmitriid/675ceff4bd07ec6cdf06a560d72...
How well does router5 work with redux? I see they have an official package for it, so it's looking good, but maybe you have first hand experience.
It makes the routes reactive. This is not necessary for smaller projects, but where it is needed this can be really helpful. The responsive route example shows this off well https://reacttraining.com/react-router/core/guides/philosoph...
It's a much more flexible model to have the router update your state in Redux or whatever, and then you take care of all the rendering and component hierarchies yourself.
We still use react-router but wrap it with code that generates all the routes off of our own object structure which describes the pages. Instead of using a string path to create links, we use page definition objects like this: `<PageLink to={Pages.user.account} />` and the custom PageLink component basically gets everything it needs to render the normal `<Link>` from the `account` object including the default display text of the link, authorization required to visit the page, etc.
Another thing we've had to do in every single project with React Router was to stop using the `history` prop and start creating our own `history` object that we can then import anywhere, not just in view code... We basically have a whole kit that wraps React Router at this point and it's much, much more predictable and maintainable than defining things in JSX.
> v5 is fully backwards compatible with 4.x
It appears the major version bump was due to package configuration changes instead of major API code changes.
All the changes were already in 4.4.0 published one day earlier, which they've now unpublished it seems.
Maintainers who have such blatant disregard for users should not be rewarded or celebrated.
I think that when someone provides an open source project they are doing everyone a favour. We then have a choice not to use it. But using their free thing is certainly not doing them a favour unless we are somehow contributing back.
There were two API rewrites in a short space of time and it was extremely frustrating, especially since it seemed almost compulsory to be experienced with React Router (along with Redux) to be taken seriously by recruiters.
For my own projects, I started using page.js years ago and haven't looked back.
Do you have a publicPath in your webpack.conf?
`publicPath: "/"`
Also make sure you a linking to="/path", not to="path"
I'm assuming that perhaps React Router is preferable beyond a certain amount of complexity? Can anyone chime in where page.js falls short?
On 10 June 2017, an mind-bogglingly ill-conceived pull request[1] was merged, which causes invalid URLs to be pushed to the browser history, breaking the back button and page refresh in many scenarios.
Ever since, users have practically been begging the maintainer to fix the bug[2] and implementing hacky workarounds[3].
In a twist of irony, the contributor who originally introduced the bug has:
a) switched their own competing router package to a different history implementation[4]
b) argued that fixing the bug (which was introduced in a patch release) would require a major version bump, implying it would be better to let it remain broken[5].
I concede that the software is open source, and nobody is entitled to make any demands of the maintainers. Nevertheless, I pity the countless end-users who are left wondering why the most basic functionality of their web browsers is broken.
[1]: https://github.com/ReactTraining/history/pull/465
[2]: https://github.com/ReactTraining/history/issues/505
[3]: https://github.com/elastic/kibana/pull/32365
[4]: https://github.com/pshrmn/curi/commit/e850bcd9297398653a79b9...
0: https://github.com/ReactTraining/history/pull/465/files#diff...
Something about HN gives people license to air all of their nitpick grievances, and make it seem like SUcH A bIg DEaL OmG WorST LiBRarY EVArR!11
To the authors, maintainers, and contributors: Thank you for making the ecosystem better. It makes our work easier.
You could prefix this to every HN thread in existence.
React-Router is reasonably good, and has some issues - like most open source libraries.
I think react-router in particular have been pretty good about sending this message with past major version changes.
One more time for those in the back:
v0.x > v1 Breaking changes
v1 > v2 > v3 a couple obscure breaking changes, but practically none
18 months pass
v3 > v4 New, composable design, basically a new project
v3 still maintained, 3.5 years no changes. v4 2 years, no changes.
v4 -> v5 was supposed to be 4.4, but an internal dependency '^' got us, so best choice was version bump to prevent problems.
I wrote my own router for Inferno/React and Mobx inspired by Vue Router. It never made much sense to me to use components to define routes, or needing to use a HoC to be able to access the router from a component.
The solution? Pinning the version to an exact number.
I always do this now as a policy, for everything, even when I'm using lockfiles though it shouldn't strictly be necessary, because I've been burned by ^ too many times. There's this ideal world expectation of ^ that it will magically give you upgrades for free without changes in behaviour, but breaking changes in behaviour occur all the time in minor and patch version updates in real world npm.
I think this is an intractable problem - mistakes will always be made, even when people try really hard, and over 100s of dependencies in a project you're therefore quite likely to see these mistakes fairly regularly.
Nice, glad to see the project becoming more stable. Upgrading from v3 to v4 made us a lot problems...