[HN Gopher] Show HN: React Routing in 120 lines (including comme...
       ___________________________________________________________________
        
       Show HN: React Routing in 120 lines (including comments)
        
       Author : ReactNative22
       Score  : 72 points
       Date   : 2022-05-13 08:49 UTC (14 hours ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | aliswe wrote:
       | Is the Preact router minimalistic, so to speak, akin to this?
        
         | ratww wrote:
         | Preact-router is more feature-complete than this one, but most
         | of the code there is due to the more ergonomic API.
        
       | janci wrote:
       | If 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 wrote:
         | You 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.
        
       | lexicality wrote:
       | Whenever 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 wrote:
         | Yeah 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/ and
         | https://eugenkiss.github.io/7guis/tasks helps keep reqs
         | constant.
        
         | delaaxe wrote:
         | You're trying to argue with a code golfing exercise
        
       | [deleted]
        
       | lloydatkinson wrote:
       | It'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.
        
         | a_wild_dandan wrote:
         | React 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 wrote:
           | It 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.
        
         | GiorgioG wrote:
         | React 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 wrote:
           | Isn't that the gap the likes of Next.js are filling?
        
           | lloydatkinson wrote:
           | Are 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 wrote:
             | we need an onomatopoeic composite here, to stop the
             | continuous arguments, maybe fribrary or lamework.
        
               | recursive wrote:
               | "lamework" feels like it perfectly captures my experience
               | of writing react apps. I'd go with that one.
        
               | bryanrasmussen wrote:
               | I 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.
        
               | tomc1985 wrote:
               | "Framurary" is kind of fun. Though lamework also
               | describes my experience with it
        
         | hobofan wrote:
         | > 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.
        
         | ratww wrote:
         | Because 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
        
           | m00dy wrote:
           | very well summarised :)
        
           | chiefalchemist wrote:
           | Agreed. 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 wrote:
             | Not sure self-edu is true in the case of React.
             | 
             | Don't forget React is a Facebook product.
        
             | ratww wrote:
             | It 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 wrote:
           | I 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.
        
             | deckard1 wrote:
             | > we'd see the same problem everywhere at the same scale
             | 
             | we do. Every C app implements its own linked list or hash
             | table library. The entire Scheme community is nothing but
             | toy interpreters of various stages of completeness (you can
             | tell a project is serious when they implement call/cc). How
             | many game engines do you think exist? It's a meme that game
             | devs like to spend more time on their pet game engine than
             | actually making their game. How many ORMs do you think
             | exist for <language-of-choice>? At least half a dozen. At
             | least. For any given language. Python, Ruby, Go[1]. ORMs,
             | in particular, seem to get created over and over again.
             | Probably because they are trivial to implement and allows
             | one to voice their opinions on SQL abstraction (bike
             | shedding).
             | 
             | [1] https://github.com/d-tsuji/awesome-go-orms
        
             | ratww wrote:
             | I 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 wrote:
               | This 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 wrote:
               | How 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.
        
               | mhoad wrote:
               | You seem to be conflating your personal experience here
               | with everything happening around you which as you rightly
               | point out is absolutely filled with this ever moving
               | target that is absolutely impenetrable to beginners.
               | 
               | The React ecosystem looks like the crypto / nft space to
               | outsiders. Nobody seems to agree on anything, no two
               | projects look alike, it's just this endless loop of
               | people reinventing the same core bits over and over again
               | for the past ten years.
               | 
               | I'm happy for you that this hasn't been you experience
               | but don't tell me that the React ecosystem is stable. The
               | reputation of the React ecosystem for many years has
               | famously been that it's a house of cards.
        
             | qudat wrote:
             | The scale of the problem on FE is because if you want to
             | work in the browser, you need to use JS. There's a
             | diversity of engineers working on the FE and with them
             | comes a diversity of ideas. People have different use cases
             | in mind and build packages to satisfy those use cases.
             | 
             | There's nothing special about JS, but there is something
             | special about being forced to use JS.
        
           | lloydatkinson wrote:
           | What 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.
        
       | ldd wrote:
       | making 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
        
       | [deleted]
        
       | kretaceous wrote:
       | I'm a big fan of Wouter[0]. Most of my routing needs are taken
       | care of by it.
       | 
       | 0: https://github.com/molefrog/wouter
        
       | deckard1 wrote:
       | I'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
        
       | fatih-erikli wrote:
       | I 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/u...
       | 
       | I use that solution in server-side and client-side so it works
       | like Nextjs.
        
         | math-dev wrote:
         | Interesting - thanks for the tip!
        
       | ThePaulAlek wrote:
       | I looked at the code in the repo and I can say that it was VERY
       | satisfying to read
        
       | yanis_t wrote:
        
       | chrismorgan wrote:
       | > 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.
        
         | woojoo666 wrote:
         | I think React tends to encourage local solutions (using a Link
         | component) over global ones (inserting a global click handler)
         | when possible. Global solutions are less composable and will
         | cause issues if you have multiple independent teams working on
         | the same page (eg maybe they need different click handlers)
        
           | chrismorgan wrote:
           | In general I would agree, but as soon as you're using
           | popstate, you've broken that completely: it's inherently
           | global and will conflict with any other compositions. Because
           | of this, the use of a global click handler will make the
           | application more consistent: either all forms of navigation
           | work, or none; whereas if you use <Link> it gives the
           | impression that you can compose, but the back and forward
           | buttons may be broken.
           | 
           | The History API, as it stands, is global state. That makes it
           | one of the very few places where I say it is better to use a
           | global solution, rather than a precise one.
        
         | math-dev wrote:
         | Would you have an example of how to do that?
        
         | wonderbore wrote:
         | > All keyboard modifiers disqualify client-side routing
         | 
         | Don't forget clicks other than "left". Middle click can open a
         | new tab.
        
           | chrismorgan wrote:
           | The 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           );       };
        
         | delaaxe wrote:
         | Better use the React root than the entire document
        
           | chrismorgan wrote:
           | I don't think the React root is really any better than the
           | document--you should either go precise, or go global, since
           | popstate is global. If there are some links you don't want
           | intercepted, they're as likely to be within the React root as
           | without it. See also my response to woojoo666.
        
       | martini333 wrote:
       | Why not describe it as 1KB minified? That's way more impressive.
        
         | franciscop wrote:
         | 1kb 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/
        
         | KhalPanda wrote:
         | Or "React Routing in 70 lines, with 50 lines of documentation".
        
         | ratww wrote:
         | The 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!
        
       ___________________________________________________________________
       (page generated 2022-05-13 23:02 UTC)