4 ms·
Using react router on one of my personal projects (~ 30k loc) was probably one of my largest regrets. At every turn it seemed designed to do the thing I wouldn’
by johnfn 8y ago
Using react router on one of my personal projects (~ 30k loc) was probably one of my largest regrets. At every turn it seemed designed to do the thing I wouldn’t expect, or have arbitrary restrictions that made my life tougher.
Some examples:
* there's no relative routes https://github.com/ReactTraining/react-router/issues/2172 https://github.com/ReactTraining/react-router/issues/2172
* there's no way to refresh the page https://github.com/ReactTraining/react-router/issues/1982 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 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 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
- mythz 8y agoI felt the same regret after each major upgrade where it seemed as breaking versions were due to unnecessary superficial API changes (which also left behind a trail of outdated docs/examples). 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.
- davedx 8y agoYup. I only use react-router when I have to (work). My other projects I always roll my own. A typical html5 push router can be really small. I don’t reinvent the wheel normally but routing is hugely overcomplicated in the react ecosystem.
- anonytrary 8y agoI feel like part of the problem with react libraries is that they implement their code "the react way" which basically means forcing it into your tree hierarchy. Dealing with dozens of higher order components gets really annoying after a while.
- k__ 8y agoDoesn't much of this go away with hooks? Before we had one hierarchy where everything was a component, logic and visuals. Now we have two hierarchies where visuals are components and logic are hooks.
- jamesknelson 8y agoYeah, this is definitely a thing. I'm a bit conflicted over it. One one hand, staying within the world of React components gives you a lot of functionality for free. And with Suspense and Hooks, the amount you can do within a component has become even greater. On the other hand, there are still things that you can't do within a component. For example, you can't easily run an async function once when the component mounts - which in my opinion, would be the perfect way to fetch data. I've been building Navi to try and create a more natural way to map routes to views and a stream of data. The thing is, the more edge cases you cover, the closer it becomes to just building React from scratch. At this point I still think that routing and data fetching is better handled externally from React, but it's less clear cut than it used to be.
- badestrand 8y agoI use preact in some of my projects and its router ("preact-router") actually does what it should: - 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.
- sebazzz 8y agoThough not in a React project, I used router5 which also offers a react component. You might want to check that out as router5 has the features you mention.
- lopatin 8y ago> there's no relative routes > 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 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.
- johnfn 8y ago> The solution to the external links issue is a one-liner. 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.
- waingake 8y agoI recently wrote a custom hook* which is serving me well so far. https://gist.github.com/tim-field/99104278abfad1b8dd94d26717335963 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 https://reactjs.org/docs/hooks-custom.html
- sorahn 8y ago> there's no relative routes https://github.com/ReactTraining/react-router/issues/2172 https://github.com/ReactTraining/react-router/issues/2172 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} /> </> ) }
- stickfigure 8y agoI also do this - 4 layers deep at times - and it works great. IMHO it's one of the more clever bits of react-router.
- sorahn 8y agoYup. My "top level routes" only have 3 paths, and everything goes from there. Thinking about routes just like components is really fantastic for react, and I don't miss having a giant central router even a little bit.
- jamesknelson 8y agoI ran into many of the same issues as you, and open-sourced my solution (called Navi). Responding to a few of your pain points: * 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/ https://frontarm.com/navi/en/
- dfa1234 8y agoThat would never be a mess like the router in Ionic 3 (they abandoned it in Ionic 4 a the bugs will never be fixed, it's a nightmare on a daily basis, and migrating from 3 to 4 is a nightmare also)
- tracker1 8y agoI've been using the `connected-react-router` wrapper for redux with react-router, and it's been very nice to use... though my router component is getting really big at this point... but still understandable.