Replies: 2 comments
-
|
https://github.com/solid-tv/solid can adopt the proposed resolution. We build a full temp object before creating the underlying WebGL object. Is construction-time access to compile-time-static props enough for your renderer? |
Beta Was this translation helpful? Give feedback.
-
|
Hi, thanks for taking this up --
Yes that satisfies the initial requirement in most cases, our idealized version would be behavior parity in this regard between our solid --
Not necessarily, maybe purely as a nice to have to track id's for debugging through reconciler operations as we don't have to rely on auto-generated ones. --
Potentially yes in the future as we move dom to native but we could also always do through microstasks so not a hard requirement. Although I would have guessed this would be able to account for non async dynamic props and get called after all the initial setProp / insert calls, but from your wording it seems like even this wouldn't? --
Yes --
Yes, happy with a conservative first version not passing it, long term given its not a question of runtime complexity and just behavior DX I would lean on having non spread props be passed statically even with a spread present |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Summary
Universal JSX currently creates host elements first and applies all props afterward through
setProp.For DOM this is usually fine because template cloning gives the DOM renderer a preconfigured node shape. For universal renderers, especially non-DOM renderers like OpenTUI, some host elements need static configuration at construction time or before children are inserted.
This RFC proposes extending universal
createElementto receive compile-time-static props:Dynamic props continue to use
setProp.Motivation
Issue: ryansolid/dom-expressions#487
OpenTUI's Solid renderer needs access to expected props during element creation. Today, the compiler emits
createElement(tag)before any props are known to the renderer. Static props are applied later throughsetProp, sometimes after child insertion. That makes it difficult for renderers whose child handling, layout, native object creation, or parent-child registration depends on parent configuration.The DOM renderer already gets an equivalent benefit through static templates: the cloned node is born with its static attributes. Universal renderers do not have that same construction-time configuration channel.
Current Universal Emit
Given:
Universal emit is approximately:
This means the renderer only sees
"box"at construction time.Proposed Emit
Pass compile-time-static props as the second argument to
createElement:Update the universal renderer contract to:
Static props included in this object would no longer be emitted as separate
setPropcalls.What Counts as Static
Static means the compiler can emit the value without creating reactive tracking.
Examples:
These can be included in the initialization props.
Dynamic expressions continue to use
setProp:The RFC does not propose untracking dynamic props to pass their initial value into
createElement. That would call dynamic expressions once during construction and again through the reactive update path, and Solid 2.0's async timing makes this more fragile.Spreads
Spreads remain runtime-managed:
The compiler cannot generally know spread contents ahead of time. Spreads continue through
spread/setPropbehavior.Open question: if static props appear before or after a spread, should any subset still be passed to
createElement, or should spread presence force all props through the current path? The conservative first version can avoid passing static props on elements with spreads.Style and Class
Open question: include static
style/classvalues in the initialization object, or keep them assetPropcalls?Including them is more consistent with "static props at construction." Keeping them separate is safer if renderer authors already rely on specialized
setProphandling for style/class normalization.Alternative: Finalize / Commit Hook
An alternative design is to keep
createElement(tag)unchanged and add a hook after static props and children are attached:This answers a different question: "tell the renderer when this subtree is ready." That may be useful for renderers that want to defer native bridge sync, layout, or parent-child registration until after construction.
However, it is a larger lifecycle addition. The immediate issue is that renderers need parent configuration before child insertion or native object setup. Passing static props to
createElementis the smaller change and better matches the DOM renderer's static-template advantage.Compatibility
This is a breaking universal compiler/runtime contract change.
Renderers currently implement:
They would need to tolerate:
A renderer can ignore
propsto preserve existing behavior, but if the compiler stops emitting staticsetPropcalls, ignoringpropsmeans static props will not be applied.Because 0.50 / Solid 2.0 is still in beta, the preferred path is to make this an unconditional universal emit change rather than support two long-term emit modes.
Proposed Resolution
Adopt
createElement(tag, staticProps?)for universal renderers.Do not pass dynamic initial values.
Do not add a subtree commit hook as part of this change, but leave it open for a future RFC if renderer maintainers identify a distinct need for "subtree finished" notification.
Questions for Renderer Maintainers
finalizeElement/commitElementhook solve a different problem for your renderer?styleandclassbe included in the construction props object?Non-goals
untrack.Beta Was this translation helpful? Give feedback.
All reactions