8 ms·
Show HN: React Routing in 120 lines (including comments)
- lloydatkinson 4y agoIt’s strange that of the numerous frameworks React seems to have the most churn, it’s had multiple ways of “doing state”, there seems to be a new router every year or at the very least a new major (breaking) version of react router. Why is routing, of all things, in such need of constant development? I say this as someone that’s made SPAs with Vue a lot and occasionally React.
- ratww 4y agoBecause making a simple router or simple state management library from scratch is quite simple. So a lot of people do them to learn how the internals work, like this case here. This makes people better programmers. Some of those folks will then decide to continue the development, put some special things here and there and release it to the world to see if anyone is interested in their version of it. Most of those are ignored, which is fine. However this makes some people vocally angry, because in theory a developer should know every single packages in the world, but never the internals. Only people of a higher class or caste should be allowed to release stuff to the world. The rest are peasants. How dare they. /s
- lloydatkinson 4y agoWhat a ridiculous hyperbolic comment in response to a question around why one particular library has a ton more development than any others in the same space.
- m00dy 4y agovery well summarised :)
- chiefalchemist 4y agoAgreed. But at the same time aren't there other things to address, to tackle. This won't be popular: but tech self-proclaimes itself as innovative and then wastes time mucking around reinventing wheel after wheel after wheel. Sure, the self-edu is helpful. Of course. But does that always have to a wheel we've seen before going down a road we've been down before? Note: Not trolling or ranting. Just looking for new thoughts and ideas.
- alophawen 4y agoNot sure self-edu is true in the case of React. Don't forget React is a Facebook product.
- ratww 4y agoIt really depends on what you mean by saying wheels are being "reinvented". Is it really wheel reinvention, or is it a small incremental evolution that fixes one pain point, but has to keep all other aspects the same? In this same thread there is a comment about how this little code snippet "throws away backward compatibility, plus everything else". New tech has to have backwards compatibility to even be taken serious by most people. But backwards compatibility requires not only reinventing the wheel, but also having it being on the exact same size and material as before so it fits where it was used. The only way to satisfy both of the groups above is to evolve tech that already exists and implement new findings in already existing libraries, but that will also enrage a lot of people. An example: React Hooks.
- andybak 4y agoI think you're being uncharitable. The reason people say this is because the scale of the problem is much, much worse in front-end javascript than in most other language communites and it's a real problem for people attempting to get to grips with best practice. If your explanation was correct then we'd see the same problem everywhere at the same scale but there's something about front-end javascript that seems to exacerbate this issue.
- ratww 4y agoI disagree that the scale of the problem is worse in the Frontend. About being uncharitable: IMO this constant mischaracterization of frontend is the real uncharitable thing here. I also do a lot of backend work and even the most "traditionally stable" programming languages (or frameworks) have a lot of churn in libraries, frameworks, patterns, toolchains, deployment methods and architectures. Which is "fine", that's how programming works! But heck, I worked recently on a 8 year old Rails app that had four different methods/libraries/frameworks being used to wrap business code. But in the frontend that would be extremely rare. If anything the frontend has been quite stable for the last 7 years or so when we settled on mostly React or Vue. The only real big change was Hooks, and even that was incremental and was an attempt to solve real problems in the ecosystem.
- mhoad 4y agoThis is basically gaslighting. F/E churn is still wild. I’m staring at an article right now titled the top 14 react libraries you must try in 2020. That’s not a normal thing for a ten year old framework.
- ratww 4y agoHow is this gaslighting? Just because someone wrote an article to profit on your FOMO doesn't mean React (and also Vue) usage in the real world hasn't been extremely stable over the years. If anything, this kind of article is the one trying to fuck with your psyche. You don't need any of the libraries in the article to make a good React app/website. Period. No, not even React-Router or Redux. And those two are probably the only ones that you'll see lots of companies/devs that actually ship stuff using. And both of them are not even that complicated, as is demonstrated in this article for the Router. Redux is also quite simple (hence why there's so many alternative implementations). If anything the ones doing the gaslighting are the ones saying that we devs need to use ultra-complex build systems and gigantic libraries to make a "real app". It's the gaslighting of saying simple architectures "won't ever work" mixed with machismo of "real programmers do X". Sure, if you want the complexity that comes with using those "must-use" libraries, feel free to have it. I won't say you're wrong by doing so. Maybe you REALLY need all 14 of them, although I doubt it. But please stop assuming that everyone is doing the same or has to. Nor try to deny the reality of me and lots of others getting things done without "14 must use libraries". Because that is the definition of gaslighting.
- GiorgioG 4y agoReact isn't a framework. In order to build an app, you have to cobble together a bunch of other libraries to use with it to build something meaningful. As someone coming from an Angular shop, I started a new job a few months ago that uses React on the frontend. My main gripe so far is there is no one "way" to do X in a react-based app. For an enterprise with lots of developers, Angular seems like a better fit - unless you want to spend months coming up with standards. Angular has its own issues of course - it's much more rigid and has a steeper learning curve.
- Rafert 4y agoIsn't that the gap the likes of Next.js are filling?
- lloydatkinson 4y agoAre people still having this strawman argument over if react is a library or a framework? Would my argument have changed if I'd put "framework/library" in my comment? No.
- bryanrasmussen 4y agowe need an onomatopoeic composite here, to stop the continuous arguments, maybe fribrary or lamework.
- recursive 4y ago"lamework" feels like it perfectly captures my experience of writing react apps. I'd go with that one.
- tomc1985 4y ago"Framurary" is kind of fun. Though lamework also describes my experience with it
- bryanrasmussen 4y agoI find React perfectly fine for writing SPAs, as long as what is being written is actually suited to being an SPA. Otherwise I find it as dreadful as any time you use a hammer to pound a screw in place.
- hobofan 4y ago> Why is routing, of all things, in such need of constant development? Because requirements change. In the last few years there was a lot of churn in React due to the introduction of async rendering and server-side rendering, and React routers were strongly affected by both of those changes.
- a_wild_dandan 4y agoReact is a view library. It deliberately focused on doing one thing, and doing it well -- declaratively painting the view layer. It's not comparable to more general/monolithic frontend development solutions like Angular/Vue/etc. Those tools have far different scopes. So of course React doesn't prescribe routing, state management, project styling solutions, build bundling, or any other frequently lamented "missing" features. They're only omissions to folks misunderstanding React's use case. Now there are solutions comparable to Vue/etc which use React -- Next.js, Create React App, etc. Comparisons, tradeoffs, and criticisms are totally fair there. Just don't blame React for churn in third party implementations of features outside of its purview. As a side note, I love that React is so narrowly scoped. It lets the community build on, experiment with, and coalesce around amazing solutions to other big features outside of React's scope. That Darwinian approach has created broad front end solutions that to me are a joy to use compared to similarly featured frameworks like Angular.
- mhoad 4y agoIt doesn’t actually do it well and has been totally out of step with how modern browsers work for years now. It’s old and poorly made technology. The fact that it chose to do one thing and it can’t even get that right says a lot about it. Sadly, for reasons that remain a mystery to me it’s one of those things like Apple or crypto where some of its loudest fans have decided to make it a part of their identity rather than a tool they enjoy using.
- ratww 4y agoReact actually does more than "one thing", and it does those things quite well, actually: First, it provides a relatively performant diffing mechanism that gives a happy medium between manual diffing and templating; it also provides reusable components that are easy to make, easy to maintain and are able to easily hold local data and have an ergonomic API; finally it also provides a sane of of passing data between layers. Other frameworks have adopted some of those concepts in different ways, and it works quite well. Other technologies have other ways of solving the same problems, and they also work! Of course, it is absolutely not perfect and doesn't solve "all problems", but that's how mature technologies generally are. Modern browsers have tried to provide a competing technology with WebComponents, but despite being native to the platform and embraced en masse not only by browser makers but by large companies, it hasn't taken off like React. Please take a time to reflect as to why something that is "there" isn't as widely used as something that requires a 50kb library to even start. And no, it's not a conspiracy, nor it is marketing. There are very good technical reasons for that. About the "fans" part: please look at the mirror. You seem to be projecting a lot here. People use React and other similar libraries because it gets the job done. A lot of your posts seem to be about competing technologies, or are anti-Apple, or anti-something. Criticism is perfectly fine, but you're the one making hating something part of your identity and the projection is blurring your ability to empathise with what others are saying.
- deleted 4y ago[deleted]
- martini333 4y agoWhy not describe it as 1KB minified? That's way more impressive.
- KhalPanda 4y agoOr "React Routing in 70 lines, with 50 lines of documentation".
- ratww 4y agoThe author's goal in this seems to be education, not really optimization or replacement of a bigger framework. And I guess this would probably be much less than 1k!
- franciscop 4y ago1kb is likely a lot more than what is shown here; I made a "tiny" but very complete React Router package which is very complete and minified+gzip it's just 1.8kb https://crossroad.page/ https://crossroad.page/
- lexicality 4y agoWhenever I see someone describe how small something they've written as a replacement for a big library is, I wonder what they've discarded in order to get it so small. Normally it's backwards compatibility, but in this case it appears to be "everything".
- jrvarela56 4y agoYeah huh? It's like 'I'm selling the cheapest bag of chips ever' and it's just cuz you're putting less chips inside lol These short libs are apples to oranges unless we have a test suite or set of acceptance criteria. Something like https://todomvc.com/ https://todomvc.com/ and https://eugenkiss.github.io/7guis/tasks https://eugenkiss.github.io/7guis/tasks helps keep reqs constant.
- ReactNative22 4y agoI don't get it...this is a simple library that people can use without bringing in external dependencies. Of course it won't be as functional as React-Router - that goes without saying!!
- lexicality 4y agoI would say that a router that doesn't support url patterns, query parameters or state is basically useless for anything other than small static sites that in my personal opinion shouldn't have clientside routing. This is a nice demonstration of how routers can work for people that are curious, but I would have a lot of concerns about it as production-worthy, especially because you're manually firing browser native events during periods that people generally wouldn't expect them to fire. I'm saying this as someone that had to write a full clientside routing system for a bespoke web app - routing is very hard and full of edge cases.
- delaaxe 4y agoYou're trying to argue with a code golfing exercise
- kretaceous 4y agoI'm a big fan of Wouter[0]. Most of my routing needs are taken care of by it. 0: https://github.com/molefrog/wouter https://github.com/molefrog/wouter
- aliswe 4y agoIs the Preact router minimalistic, so to speak, akin to this?
- ratww 4y agoPreact-router is more feature-complete than this one, but most of the code there is due to the more ergonomic API.
- ThePaulAlek 4y agoI looked at the code in the repo and I can say that it was VERY satisfying to read
- ReactNative22 4y agoThanks :) :)
- janci 4y agoIf I read this correctly, all the route components are evaluated (i.e. rendered to virtual DOM) and only then one of them is selected and shown (i.e. rendered to HTML DOM). This seems utterly inefficient, even for educational example.
- ratww 4y agoYou read that incorrectly. Only the active route component is returned by the Router function, therefore React's render() won't do anything with the others.
- chrismorgan 4y ago> event.metaKey || event.ctrlKey This misses event.shiftKey. All keyboard modifiers disqualify client-side routing. As for <Link> in its entirety, where you have to use a special component which becomes a link and adds a click handler to it, I think this is generally the wrong solution: it’s better to instead put a single click handler on the entire document to intercept clicks on links. That way, you can just use normal links everywhere and it just works, rather than having to remember to use a whole separate component every time which may or may not be able to pass through the required properties or attributes (e.g. this one only supports class and href). Simpler, smaller and cheaper.
- wonderbore 4y ago> All keyboard modifiers disqualify client-side routing Don't forget clicks other than "left". Middle click can open a new tab.
- chrismorgan 4y agoThe middle mouse button doesn’t trigger a click event, but rather auxclick (like right click also doesn’t, but rather contextmenu and then auxclick if that’s preventDefaulted). But there are definitely situations where it’s judicious to check event.button, and I missed altKey, too. Here’s the full function Fastmail uses: const isClickModified = function (event) { return ( !!event.button || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey ); };
- wonderbore 4y agoAh indeed, I probably confused it with other mouse events that do not have a button-specific event like `auxclick` and `contextmenu`. Mouse down/up only use the button to differentiate the buttons, which can also explain why that function includes such check (even if unnecessary on the `click` event) On a side note, I can't believe we still don't have a `visit` or `activate` event that works regardless of hardware, without having to exclude modifier keys.
- 4y ago
- fatih-erikli 4y agoI use it like that and I am pretty happy with it. There's one thing, you should redirect all the pages to one single endpoint in server side order to use "pushState". Otherwise it will return 404 when you hit the refresh button. If you don't own a server, you can support routing with hashtag "#" and listen to "onhashchange" event instead of "popstate". Also, if you would like to support nested and dynamic routes (it's not possible with that code snippet in the github repository since it just checks like `path===currentPath`), you might look at the following solution: https://github.com/fatih-erikli/universal-router/blob/main/use-universal-router/index.ts#L14 https://github.com/fatih-erikli/universal-router/blob/main/u... I use that solution in server-side and client-side so it works like Nextjs.
- chrismorgan 4y agoPlease don’t encourage using a single route and the hash; people should just ensure that suitable document is served from all routable URLs—whether it be a consistent bootstrap file, or (generally preferably) that you do server-side rendering. Using the fragment for routing is only something to do when you can’t do it the proper way, not a tool to reach for from the start.
- math-dev 4y agoInteresting - thanks for the tip!
- ReactNative22 4y ago> There's one thing, you should redirect all the pages to one single endpoint in server side order to use "pushState". Otherwise it will return 404 when you hit the refresh button. If you don't own a server, you can support routing with hashtag "#" and listen to "onhashchange" event instead of "popstate". Could you explain this one a bit more / maybe some example code I could borrow from? :)
- ReactNative22 4y agoThanks for this!
- deleted 4y ago[deleted]
- yanis_t 4y ago
- ldd 4y agomaking React small libraries like these is fun. I made one myself that was absolutely the simplest I could go for[0] 0: https://github.com/ldd/react-simplest-router https://github.com/ldd/react-simplest-router
- deckard1 4y agoI've used a lot of routers and my favorite is still page.js[1]. It hasn't been updated in years. But it's small, is Express-compatible (i.e. server/client routes can use the same code), and, more importantly, is hackable. I'll never use a router tied to a certain framework again (react, nextjs, etc.) because you trade flexibility for perceived convenience (e.g. using folder structure as route structure, or React component tree as route structure). But it's a terrible trade-off that paints you into a corner later, IMO. Routing can get really niche and site-dependent, so having it fully under your control is worth it. [1] https://github.com/visionmedia/page.js https://github.com/visionmedia/page.js