[HN Gopher] Making sense of React Server Components
___________________________________________________________________
Making sense of React Server Components
Author : joshwcomeau
Score : 73 points
Date : 2023-09-06 16:27 UTC (3 hours ago)
(HTM) web link (www.joshwcomeau.com)
(TXT) w3m dump (www.joshwcomeau.com)
| mattaw2001 wrote:
| [flagged]
| mattaw2001 wrote:
| [flagged]
| idosh wrote:
| [dead]
| rabuse wrote:
| Hilarious that the industry is going full-circle back to server
| rendered pages.
| jbverschoor wrote:
| Basic thing every so many years. Waste of life
| MPiccinato wrote:
| I will have to give this article a more full read rather than
| just a skim, but...
|
| I am left with such confusion as to how React/Next arrived at
| this solution. `useEffect` didn't run on the server when doing
| SSR, great, easy enough to understand. Now several common hooks
| don't run on the server because they are considered interactive?
| And it isn't that they won't run, their initial pass in most
| cases doesn't do anything, it is that Next now yells at you for
| having a `useState` hook in a "Server Component".
|
| I would like to write a component, not have to think about where
| it is running in most cases, and go on with my day. I mostly use
| React for large SPAs and have adopted Next for doing SSR on the
| few pages that I needed it for (SEO, etc).
| halfmatthalfcat wrote:
| It's annoying that the React team announced Server Components
| without a well defined spec, the wire protocol most
| significantly. Instead, it's a cabal between the React team and
| Vercel which obviously is going to give them an inherent
| advantage and probably steer things in their favor, rather than
| the broader React ecosystem as a whole.
| quonn wrote:
| It seems like there is a project on github called simple-rsc
| that works without Next.
| rco8786 wrote:
| I'll do what I did the last time one of these articles popped up.
| Word counts:
|
| complex: 2
|
| confusing: 3
| [deleted]
| lioeters wrote:
| > As I write this, there's only one way to start using React
| Server Components, and that's with Next.js 13.4+
|
| I don't understand how this is acceptable to the React user
| community, that only Vercel gets to be in this privileged
| position. Why did they not include other companies, or the users
| themselves, in the discussion and development of this feature.
|
| > Since Server Components are a new React feature, third-party
| packages and providers in the ecosystem are just beginning to add
| the "use client" directive to components that use client-only
| features like useState, useEffect, and createContext.
|
| > Today, many components from npm packages that use client-only
| features do not yet have the directive. These third-party
| components will work as expected within Client Components since
| they have the "use client" directive, but they won't work within
| Server Components.
|
| The arrogance of expecting all third-party packages, React-
| related or not, to buy into the "use client" directive. A humbler
| approach would have been a "use server" directive to opt-in to
| this behavior, instead of expecting the _entire rest of the
| ecosystem_ to adapt to it.
| foota wrote:
| Reading further, use client is viral, and propagates to
| children components.
| [deleted]
| adamesque wrote:
| The reason Vercel was selected for this privilege is pretty
| simple, to my understanding: they volunteered and committed
| engineering resources to partner with the React team to work
| through a pretty major and experimental new API with a lot of
| expected breaking changes.
|
| Child of a sibling comment has more details:
| https://news.ycombinator.com/item?id=37408918
| paulddraper wrote:
| Facebook open source has been quite good (React, GraphQL, Buck,
| PyTorch).
|
| This is...weird. How did Vercel manage that?
| marksomnian wrote:
| Dan Abramov (React core team, formerly of Meta) talks about
| this in a Twitter thread:
| https://twitter.com/dan_abramov/status/1654688751342301184
|
| In short, it's because Vercel invested engineer-years into
| piloting RSCs as part of a production framework and making
| Next the guinea pig. Next wasn't actually the first framework
| to try RSCs - Hydrogen (Shopify) and Gatsby both tried early
| versions of it and provided feedback, but Next is the first
| to implement it to the point that it can be considered
| stable.
|
| The long-term goal is that RSCs aren't a Next-only concept -
| for example the Remix team said that they wouldn't implement
| them until they became more stable (https://twitter.com/ryanf
| lorence/status/1678416472010260480), but are working on it
| now (https://twitter.com/ryanflorence/status/1697253955376722
| 092). But the React team has always historically favoured
| trying new features in production to iterate on the API (this
| happened a lot internally at Meta), and this was an
| opportunity to do that.
| tshaddox wrote:
| Also worth noting that after experimenting with RSCs in
| Hydrogen, Shopify acquired Remix and is now building
| Hydrogen using Remix.
| TheCoelacanth wrote:
| Third-party packages don't need any directives unless they
| specifically want to put a client/server boundary in their
| component.
|
| The directive marks where the transition from server to client
| happens. If you aren't already starting in a server component,
| then you don't need to do anything to use client features.
| Gunax wrote:
| Server side rendering isnt special any more:
|
| https://joshcollinsworth.com/blog/antiquated-react#server-si...
|
| This blog was posted to HN a few weeks ago. The author does a
| really good job of summarizing React's relationship with the rest
| of the SPA ecosystem.
| TheGeminon wrote:
| > Instead of bouncing back and forth between the client and
| server, we do our database query as part of the initial request,
| sending the fully-populated UI straight to the user.
|
| > But hm, how exactly would we do this?
|
| Couldn't help but chuckle. What mysterious technology could allow
| us to send an entire fully-populated UI over the web?
| benatkin wrote:
| > What mysterious technology could allow us to send an entire
| fully-populated UI over the web?
|
| WebAssembly? Just kidding. But I think a lot don't realize that
| you _could_. It 's pretty well supported now and a small
| WebAssembly library can fit in about the same size as a full
| page photo.
| gabereiser wrote:
| Vugu?
| gabereiser wrote:
| "As if a million voices cried out in terror and were suddenly
| silenced" - The full circle. When they left us, they were but
| learners, now they have become masters. Realizing that this
| nirvana exists, that people have been doing it this way for
| ages. That a combination of interactivity with the offloading
| of compute and rendering is a good thing for their performance.
| That grey beards really do know a thing or two. /s
|
| All sarcasm aside, having composable components server-side is
| only a good thing. I welcome it.
| nwienert wrote:
| We already had composable components server side with SSR,
| they just didn't query data inside the render loop. But that
| doesn't really gain much, if anything leads to slower overall
| performance as now instead of doing something like GraphQL
| and resolving your entire tree in a single optimized database
| call, you're probably waterfalling all over the place.
| hotnfresh wrote:
| GraphQL hype is (and always has been, really) out of
| control.
|
| GraphQL doesn't do a damn thing to help you optimize your
| database calls. It also doesn't do a thing to help with
| security or preventing DOS-inducing queries, which is the
| first question anyone who's been around this block before
| (exposing remote query interfaces) has about it.
|
| Some big frameworks that happen to speak graphql will
| automagic that stuff for you _in simple cases_ , but we
| don't claim e.g. the capabilities of the Rails framework
| with rails-api et c. as capabilities of REST or SQL or
| whatever.
|
| This stuff is really annoying because you get half-
| technical leadership (or non-technical) thinking graphql is
| magic and that it's good for all kinds of things it's not
| and that it'll save lots of time that it won't, between the
| hype and the name.
| paulddraper wrote:
| GraphQL is for (1) static typing (2) front-end developer
| productivity and (3) front-end latency.
|
| Maybe it does those well, maybe not, but if you expect it
| do anything else, you'll certainly be disappointed.
| gabereiser wrote:
| who's to argue that you didn't fetch your entire tree in an
| optimized way and passed that to your render loop as props?
| I think there's patterns for this. I'm not arguing that we
| haven't had the capability of composability with SSR, we
| definitely have. What I'm arguing is that merging the two
| worlds of front-end and back-end in a singular nomenclature
| (besides just typescript) is good for velocity. Or maybe
| I'm just inviting more pain as mixin's become traits and
| the waterfall of bugs comes our way.
| paulddraper wrote:
| The Star-Bellied Sneetches
| [deleted]
| foota wrote:
| This is my first time really reading about them, I'd assumed
| they'd do some ASPX style interactivity where server components
| updates on the server and send back html, it's interesting that
| they haven't tried to go for something like that, meaning this is
| a lot more limited in scope in some ways than I'd thought.
| marksomnian wrote:
| If you mean updating the page as the result of a mutation,
| Server Actions (https://nextjs.org/docs/app/building-your-
| application/data-f..., still in alpha) can do that - Next can
| re-render a route and send the newly updated UI as part of the
| response (this is a Next-specific feature, but I can't see why
| other frameworks couldn't implement a similar pattern around
| RSCs).
| xixixao wrote:
| > In order for this to work, we'd need to be able to give React a
| chunk of code that it runs exclusively on the server, to do the
| database query
|
| This is not true/it's misleading. What you need is to be able to
| fetch on the server, and hydrate on the client using data from
| the server. This is possible with SSR and injecting into the
| React stream, using isomorphic (client) components.
|
| The article is great, but the reasons for RSC are more
| subtle/complicated than the flow of the article would imply.
| xixixao wrote:
| You can see a live demo of this here (using Remix and
| https://github.com/brillout/react-streaming): https://blessed-
| ibis-783.convex.site/
|
| The relevant isomorphic data fetching hook source code is here:
| https://github.com/xixixao/convex-hosting/blob/main/app/hook...
| bdcravens wrote:
| so ... ColdFusion custom tags?
| kraig911 wrote:
| I legit spit out my coffee when I read this.
| swyx wrote:
| its actually something thats been discussed before https://tw
| itter.com/floydophone/status/1462928358988156932?s...
| benatkin wrote:
| > This tutorial is written primarily for developers who are
| already using React
|
| Also good for those moving away from React, since we understand
| React too. Probably won't change it, but may give us things to
| look for in our new frameworks. A former coworker who was
| _really_ into React just switched to Flutter.
| cageface wrote:
| I just started building a new app in Flutter too after working
| exclusively in React for the last several years.
|
| I'm not sure I'd use Flutter for the web yet but I definitely
| prefer it to React Native.
| benatkin wrote:
| I like how Flutter is truly different. I learned just how
| different it is because it has a completely different
| problem, shader compilation jank. It shows what great risks
| the Flutter team took to create something innovative. It's
| paying off, and time will tell how big it will be!
| https://docs.flutter.dev/perf/shader
| cageface wrote:
| I think it really comes down to Google's level of
| commitment to Flutter. They've done a lot of great work so
| far and I think it could easily become the first choice for
| cross platform app development if they investing in it to
| the degree they have so far.
| megaman821 wrote:
| The more features React adds the less I end up using React. The
| new additions are just so inelegant, and don't fit my brain. The
| function useEffect has so many caveats and such a terrible API. A
| magic "use client" string at the top of a file is just
| ridiculous. React code is nearly impossible to understand and
| write without extensive external documentation now. I feel sad
| for the future developer that has to modify this type of code ten
| years from now; I hope Google is good at searching decade old
| documentation to figure out what the hell is going on in old
| React code.
| champagnepapi wrote:
| Agreed. IMO, it all started with Hooks. Things really went
| downhill from there. useEffect is terrible! Example, how easy
| it to forget the dependency array?! Because of that, you have
| to setup linting rules to fix the poor API provided by that
| hook...
| paulddraper wrote:
| HN is a funny place.
|
| A useful feature that an insane majority of React devs have
| come to prefer is "downhill."
|
| Kids these days.
| danielvaughn wrote:
| I find it's mostly the kids who like hooks, and the older
| devs who've been around since jQuery or further back, who
| dislike them.
| Scarblac wrote:
| I'm 49 and started with the Commodore 64, and function
| based components with hooks are _so much cleaner_ than
| the old class based components, it 's unbelievable.
|
| The classes had closely related functionality spread out
| over several different methods making them hard to
| understand at a glance, function based components are
| very concise.
|
| I think people who dislike hooks tend to overuse
| useEffect (it's rarely needed) and to do too much inside
| components rather than inside custom hooks.
| tshaddox wrote:
| For what it's worth, that's not at all my experience on
| the teams I've worked with. I was around when hooks were
| released and it was an immediate and significant
| improvement to our team at the time.
| bgirard wrote:
| I think this is an artifact of HN's voting system. Most
| readers probably don't have enough karma to even downvote.
| For the ones that do, guideline discourage downvoting for
| comments that you disagree with.
|
| And I can see why the majority of HN readers would upvote
| the top level comment. Particularly since it's a popular
| re-hashed opinion.
|
| Top comments aren't a good survey of the opinions of a
| specific community for that reason.
| keb_ wrote:
| Many folks were criticizing hooks when they were
| introduced.
|
| Of course React devs will "prefer" it; they are the
| idiomatic way to adding state/triggering effects in React.
| [deleted]
| Gunax wrote:
| Every other framework not only has its own implementation of
| hooks, but notably: every one of them is faster, smarter,
| easier to write, or a combination of all three.
|
| I agree that useEffect is bad.
|
| But there are other SPA frameworks that do things better. In
| fact, just about _any_ other framework does things better.
| hotnfresh wrote:
| Hooks felt like a big make-work project to let folks claim
| high-impact commits on a project that didn't really need any
| of those, anymore.
| politelemon wrote:
| What does this expression mean, make-work project?
| hotnfresh wrote:
| Digging a hole and filling it back up again. Work for the
| sake of having something to do.
| politelemon wrote:
| Ah I understand it now thanks. Not an uncommon thing in
| many places!
| fidotron wrote:
| It will turn out to be a great conspiracy where the React team
| are being encouraged to make it so only LLMs can make sense of
| React code in future.
| paulddraper wrote:
| > The function useEffect has so many caveats and such a
| terrible API.
|
| Really? What caveats?
|
| The only maybe oddity that I can think of is that if the deps
| array is omitted it always runs.
|
| What API would you prefer? Something more like signals?
| danielvaughn wrote:
| This may be a personal thing, but I really like reading and
| writing code that feels like it's telling a story. That is,
| operating sequentially (this happens, then this happens, then
| this other thing, etc).
|
| useEffect breaks the sequential nature of your code and makes
| it feel like you're reading a script from a Quentin Tarantino
| movie.
| littlecranky67 wrote:
| Agreed, but non-sequential execution is the nature of
| event-driven, async non-blocking code. Event-driven as Web
| Applications (not Websites!) mostly deal with events (user
| input or network events). As long as the JavaScript VM and
| the DOM uses non-blocking async models no framework - being
| it Vue, Angular, React or whatnot - will ever change that.
|
| Sequential, blocking modells like i.e. batch ETL jobs are
| just not the domain of the browser.
| SinParadise wrote:
| Not useEffect specifically, but wiring something very
| stateful like a map library into the React rendering paradigm
| while keeping the state management in React via useState etc.
| can be very difficult to do so in a performant way.
|
| I recalling using a lot of useRef to manually tune when to
| re-render, and in an ideal world I shouldn't be this granular
| about it.
|
| You can certainly use one of the many React map wrapper
| libraries to lessen the pain, the pain is still very real,
| just dealt with by someone else.
| nwienert wrote:
| But what's better? In the end you need control over stuff,
| it's almost like people want frontend to be magically easy
| but unfortunately there's just the reality that either you
| have high abstraction but less control, or low abstraction
| and more control (more code, more gotchas, etc) until you
| get a smart optimizing compiler ofc.
|
| Hooks imo are great, as they are pretty explicit and low
| level.
|
| Nowadays signals are the new kid on the block, though mobx
| and similar have existed since forever in react land, but
| they have their own crazy edge cases like reactive loops
| and implicit behavior.
| paulddraper wrote:
| > and in an ideal world I shouldn't be this granular about
| it
|
| Hm, could you give an example of this ideal performant
| state management world? Angular? Vue? Svelte? MobX?
| keb_ wrote:
| Svelte is a good example. But you don't have to go that
| far; Solid and Preact have signals with auto-tracked
| dependencies.
|
| As another commenter mentioned, yes it's less low level
| than managing your own dependencies, but then again, most
| React apps are already wrapped in layers and layers of
| abstractions/context providers/selectors and use Jest as
| their test runner (which injects the global namespace
| with functions) and does other black magic and weird
| metaprogramming, so I think most React devs are already
| OK with less lower level stuff.
| Izkata wrote:
| It does a shallow compare, not a deep compare. Workarounds
| tend to involve additional hooks:
| https://dev.to/vsramalwan/ways-to-handle-deep-object-
| compari...
| keb_ wrote:
| The dependency array is a huge footgun. Engineers,
| experienced and newbie alike, get it wrong all the time
| (either causing infinite render loops, or skipping necessary
| re-renders). This affects useCallback and useMemo as well.
| After a while, I stopped thinking "oh the developers just
| aren't doing it right" and more "the React team can do better
| than this."
|
| > What API would you prefer? Something more like signals?
|
| Yes. Or full tree redraws like Mithril.js did 8 years ago.
| tshaddox wrote:
| Or you installed the lint rule once 4 years ago and never
| had a problem again.
| gyanreyer wrote:
| Agreed, everyone who complains about dependency arrays
| almost certainly hasn't used the linting rule. That being
| said, I'm not sure that an API is well-designed if the
| only way to use it effectively is by forcing you to even
| know there is an eslint plugin to begin with, and then
| once you do know that, that means now you're being forced
| to add eslint to your project whether you like it or not.
| And sometimes eslint just stops working for who knows
| what reason, I have a developer on my team who's
| constantly dealing with issues where his eslint/prettier
| setup isn't running correctly.
| paulddraper wrote:
| React does full tree redraws (well, unless you use memo).
|
| useEffect is for side-effects.
| Izkata wrote:
| Class components have "shouldComponentUpdate()" that
| avoids this entirely.
| keb_ wrote:
| It does not. Child components will only render when their
| parent component re-renders or for example, its state
| changes.
|
| Either way, this is different than what I mean with
| Mithril.js (it does full tree re-renders on event handler
| calls or when a manual redraw function is called).
| foota wrote:
| Personally, I grew to prefer signals and rx and APIs for
| heavy things. I wish it were easier to hook up some custom
| class object to a component to use as state, but it always
| feels clunky.
| cjcenizal wrote:
| This page[0] lists many situations in which useEffect
| shouldn't be used. Some might seem counter-intuitive.
|
| [0] https://react.dev/learn/you-might-not-need-an-effect
| paulddraper wrote:
| tl;dr Don't use useEffect if there is an alternative.
|
| That's a bunch of examples where there are good
| alternatives.
| consilient wrote:
| That's not a bunch of separate caveats, it's a few
| principles illustrated with lots of examples.
|
| - Don't use effects for things that aren't genuinely
| effectful
|
| - Put finnicky state management stuff in reusable utils
| instead of re-implementing it from primitives over and over
| again.
|
| Neither is React-specific.
| johngalt2600 wrote:
| Agreed. React is great but I really do not enjoy writing it.
| Much prefer Vue
| bakugo wrote:
| > I hope Google is good at searching decade old documentation
|
| Google isn't even good at searching recent documentation, from
| my experience.
___________________________________________________________________
(page generated 2023-09-06 20:01 UTC)