Bloomca / veles

UI library with main focus on performance
https://bloomca.github.io/veles/
MIT License
48 stars 0 forks source link

Add Context support #34

Closed Bloomca closed 5 months ago

Bloomca commented 5 months ago

Right now there is no support of Context in any capacity. So the assumption is that the state will be managed globally somewhere in the form of a singleton, which tracks with another assumption I make that this library is more suited to very interactive complex interfaces.

That being said, I think Context support can be beneficial for better components composition (e.g. make a component library, even an internal one).

We already have a full tree when mounting components. The problem is that it has no full reference to parents outside of HTML nodes, so we can either:

Realistically, Contexts don't override each other very often, and usually Context is stored at the very top level, which makes me hesitant to traverse the entire components tree to get to the top to read Context every time.

Maybe all Contexts can be kept in a lookup table or something, as I've said, it will mostly be used the same across all components.

Also Context will 100% be non-reactive. So the idea would be to store a stable reference there (state, or another stable store like Redux or Zustand) without any API to update it.

I don't consider it an urgent matter, but it will be needed in the future.

Bloomca commented 5 months ago

I gave it a try, because in theory it sounded very close to how lifecycle hooks context is implemented (ref), but it is definitely more tricky.

The difference is that lifecycle Context is fully independent for each component and in general the order does not matter. Here, though, there is a case when we pass children into another component:

<MyComponent>
  <AnotherComponent />
</MyComponent

This is translated into:

createElement(MyComponent, { children: [createElement(AnotherComponent)] })

And function arguments are executed first, before calling the function itself. If the function changes Context, the child component will be evaluated incorrectly.


To solve this problem, we basically need to break down components rendering into 2 steps. First create an object, and then later render it afterwards in the order they appear in the tree.

The problem here is that I don't see any way to do it without:

  1. build the tree
  2. traverse the tree fully and turn components objects into actual markup (this will need to happen recursively)

As my goal is to focus on performance, I am not sure traversing a potentially very big tree is a great idea. I'll keep thinking about it, maybe I am missing a way to execute these components in place somehow but in a correct order.