top | item 44717289

(no title)

patrickthebold | 7 months ago

I've been toying with an idea of a pattern. I'm curious as to if it has a name. I'll write a blog post once I have an app using it. In the meantime, it's (roughly):

  - No Hooks.
  - Don't try to sync any state. E.g. keep a dom element as the source of truth but provide access to it globally, let's call this external state.
  - Keep all other state in one (root) immutable global object.
  - Make a tree of derived state coming from the root state and other globally available state. (These are like selectors and those computations should memoized similar to re-select)
  - Now imagine at any point in time you have another tree; the dom tree. If you try to make the state tree match to dom tree you get prop drilling. 
  - Instead, flip the dom tree upside down and the leaves get their data out of the memoized global state. 
  - Parent components never pass props to children, the rendered children are passed as props to the parent. 
You end up with a diamond with all state on the top and the root of the dom tree on the bottom.

One note, is that the tree is lazy as well as memoized, there's potentially many computations that don't actually need to be computed at all at any given time.

You need something like Rx to make an observable of the root state, some other tools to know when the external state changes. Some memoization library, and the react is left with just the dom diffing, but at that point you should swap out to a simpler alternative.

discuss

order

agos|7 months ago

you can do something like this with most global state libraries, Jotai to name one. But very soon you'll see that you need effects there, so you'll need that global state solution to be rock solid in that aspect

patrickthebold|7 months ago

I happen to also have thought about this. Effects would listen to the global state and if needed do their side effect and update the state. As a type it's just State -> State, with an implicit side effect.

As an example: Say the user clicks a button to submit a form, clicking the button updates the local state to include something like `status: 'SUBMIT_REQUESTED'` then you make the request conditionally, and update the state to `status: 'IN_PROGRESS'`.

It might become a mess, but the point is to do no side effects based on any events, all effects happen conditionally based on the state. My hope is the forces you to actually track everything you should be tracking in your state object.