Fork me on GitHub
#react
<
2022-04-09
>
orestis12:04:45

Hey, React 18 was announced with the first stable support for Concurrent rendering. Our app was stuck still at 16.8 but 17 looks like an easy move. I'm updating reseda to use the new useSyncExternalStore hook which is backwards compatible.

orestis12:04:28

I will keep exploring React 18 and report back. Any others who have had a look?

lilactown15:04:32

ive been using it with helix. usetransition and usedeferred are cool

lilactown16:04:10

we are also stuck on 16 at work :D

lilactown16:04:44

i spent a sprint trying to upgrade and decided to put it off. they changed the way events bubble which breaks some of our most complex code

orestis17:04:16

I've created a PR for reseda that updates the internals to use React 18: https://github.com/orestis/reseda/pull/14 -- the public API remains the same which is a great relief. I will try to see if I can get it to work with both React 17 and 18. Shame that package.json can't easily allow me to test with both. (I wish I had an alias like in clj).

orestis17:04:14

Regarding useTransition, the great big caveat is that it doesn't work with "external stores" (like Redux, Reseda, et al). You can use useDeferredValue to get the same effect. I have added demos in Reseda that show the differences: https://deploy-preview-14--heuristic-jones-e1e7ad.netlify.app

orestis17:04:23

That is to say, you can still wrap a "dispatch" or whatever it's called (in reseda, just a swap! in a startTransition but it will be still be considered "sync" or "urgent" - and in particular, you will get suspense fallbacks replacing existing content which is very very annoying. Thankfully useDeferredValue will turn the render into a non-urgent one and essentially you will re-render with an a previously resolved promise, meaning you won't get any fallbacks. It works nicely.

orestis17:04:49

The Suspense stuff is apparently still brewing, but I hope that it won't be another 3.5 years until they release it 🙂

lilactown17:04:55

the streaming ssr stuff is the most interesting and most out of reach for me right now

lilactown17:04:57

a lot of code would go away if we could just query the db in a component

Aleed18:04:02

does streaming ssr make this possible? i also imagine it would be limited to js/cljs, making it less useful for clj databases?

lilactown04:04:16

if one wrote a compatible library for clojure, you could define components in a CLJ(C) file that would talk to your database on the backend and stream the result to the React front end

lilactown04:04:42

but this requires reimplementing React's streaming API in Clojure 😄

orestis05:04:25

You're talking about Server Components, right?

lilactown16:04:31

not quite. the difference is streaming rendering sends HTML over the wire and only handles initial page load, whereas server components use a custom wire format and can be triggered at any point in the page's lifecycle

lilactown16:04:06

you can imagine 3 different protocols:

(defprotocol IRenderHtml
  (-to-string [el sb])
  (-to-stream [el s]))

(defprotocol IRenderServer
  (-to-wire-format [el ctx]))

(defprotocol IRenderClient
  (-to-fiber [el ctx]))

lilactown16:04:25

IRenderClient is handled by React on the client and I don't want to rewrite it. the other two protocols though are used on the server and we'd have to reimplement them and the runtime engine in Clojure to use them

orestis17:04:45

I've resigned to have to use node for any kind of SSR. A small experiment today shows that since useEffect doesn't run on the server, data fetching is still an issue that isn't solved by React 18. They say so themselves. Until then, the only thing that makes sense (for our app) is a UX improvement of getting to a “skeleton” page early.

orestis17:04:08

Perhaps instead of Node we might be able to use Graal.js

orestis17:04:47

But again, as far as I have understood, the wire format you talk about is still brewing, and not even available in React 18

lilactown20:04:53

on the server you don't fetch using useEffect, you suspend - just like on the client with React 18

lilactown20:04:37

IIUC streaming SSR allows you to render a suspense boundary and then stream the result later, but maybe I misunderstand

lilactown20:04:12

I do know that it allows partial hydration, which is very useful as you said for quickly getting the page rendered on initial load

lilactown20:04:35

but yes I'm waiting for the wire format to stabilize before thinking too hard about how to implement it in Clojure