larsthorup / rsc-spike

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

rsc-spike

Experiment in implementing React Server Components without using a framework, a bundler or any other dependencies

Without React:

open html/index.html

With Client Side React:

(cd hydrate && npm start)

With Server Side React:

(cd react && npm start)
  • Without React
    • Pass server props to client components
    • Server actions
  • With client side React
    • hydrateRoot
    • include reactJSON in HTML
    • generate reactJSON from App.js
    • components
    • render HTML from clientJSON
    • renderStyle
    • skip server side rendering of function props, like onChange
    • hydrate client components manually
    • hydrate client components from JSON
    • hydrateRoot(document)
    • navigation (which is where hydrateRoot is leveraged)
    • server action
  • With plain React
    • Async server components
    • Fetch "react" and "react-dom" UMD in client
    • importmap to enable isomorphic import from "react" (branch: "isomorphic-react-wip")
    • Hydration
    • Client components

Goals:

  • No dependencies but React
  • Example app
  • One tree
  • Initial fetch contains pre-rendered HTML
  • Server components rendered on server
  • Server components not imported on client
  • Importing client components switches to client rendering
  • Client components re-renderes on client
  • Nesting client components in server components (upvote button)
  • Nesting server components in client components (top-level dark/light mode toggle)
  • Server components can access server resources (like database)
  • Server components can use heavy libs (like syntax highlighting)
  • Client components can access client resources (like click events)
  • Testability

Non goals

  • Developer Experience
  • Bundler
  • TypeScript
  • Tests

Questions

  • How are server side props passed to client for hydration?
    • They are included in the serialized reactTree
  • Must the entire reactTree be sent to the browser, essentially duplicating the HTML?
    • Yes!
  • How to include the markup but not the event handler in a client <UpvoteButton />?
    • We want to include the button to avoid layout shift
    • We want to postpone the button to avoid click before active
    • Can we use a headless pattern?
      • Parent: client component that has all event handlers and state
      • Child: server component with markup
    • The server simply also renders client components
  • How is a server action invocation serialized to a request and a response?
    • Generate an async client function that calls fetch()
    • Wrap the server action with an API end-point handler
  • How to render an async server component?
    • Use renderToPipeableStream
    • Use react@18.3
  • Can client components import server actions
    • Yes
    • So only server components ("use server" functions that return React.Element) is prevented from being called from "use client" functions
  • Why must the client bootstrap script import all server components to hydrate?
    • Seems to load too much JS code to the client...?
  • Why is there no react-dom/client UMD build?
    • Loading react-dom gives "React.Scheduler is undefined"
    • Also load the "scheduler" package!
  • Why is top-level "this" undefined when importing a UMD bundle from a module?

RSC

  • RSC bundler creates bundle with client components and server action client functions
  • RSC server run top server component (App) to build reactTree
  • RSC server render client components gets placeholders?
  • RSC server render reactTree to HTML
  • RSC server serialize reactTree to reactJSON
  • RSC server embeds reactJSON in HTML
  • RSC server embeds <script> link to RSC client in HTML
  • RSC server embeds <script> link to client component bundle in HTML
  • RSC server respond with HTML
  • Browser renders HTML
  • Browser loads RSC client
  • RSC client derializes reactJSON into reactTree
  • RSC client hydrates DOM with reactTree
  • Browser imports client components from bundle
  • RSC client instantiates the placeholder client components
  • Browser imports server action client functions from bundle
  • server action client function sends request to the server
  • RSC server routes request to server action

Inspiration

Videos:

Blogs:

About

License:MIT License


Languages

Language:JavaScript 95.1%Language:HTML 4.9%