react

orestis 2022-04-09T12:18:45.367639Z

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.

orestis 2022-04-09T12:19:28.617289Z

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

lilactown 2022-04-09T15:59:32.216109Z

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

lilactown 2022-04-09T16:00:10.414139Z

we are also stuck on 16 at work :D

lilactown 2022-04-09T16:01:44.835899Z

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

orestis 2022-04-09T17:28:16.390809Z

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).

orestis 2022-04-09T17:32:14.380779Z

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

orestis 2022-04-09T17:39:23.729859Z

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.

orestis 2022-04-09T17:39:49.267229Z

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

lilactown 2022-04-09T17:40:55.956349Z

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

lilactown 2022-04-09T17:41:57.213529Z

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

Aleed 2022-04-09T18:43:02.452389Z

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

lilactown 2022-04-10T04:30:16.917519Z

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

lilactown 2022-04-10T04:30:42.318129Z

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

orestis 2022-04-10T05:56:25.026389Z

You're talking about Server Components, right?

lilactown 2022-04-10T16:14:31.082319Z

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

lilactown 2022-04-10T16:18:06.395719Z

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]))

lilactown 2022-04-10T16:19:25.983569Z

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

orestis 2022-04-10T17:53:45.231699Z

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.

orestis 2022-04-10T17:54:08.666919Z

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

orestis 2022-04-10T17:54:47.850959Z

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

lilactown 2022-04-10T20:48:53.835329Z

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

lilactown 2022-04-10T20:49:37.053109Z

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

lilactown 2022-04-10T20:50:12.891319Z

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

lilactown 2022-04-10T20:50:35.246519Z

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