Skip to content

Allow isolated, nameless components, introduce 'component_'#905

Merged
dmjio merged 27 commits into
masterfrom
nameless-components
May 3, 2025
Merged

Allow isolated, nameless components, introduce 'component_'#905
dmjio merged 27 commits into
masterfrom
nameless-components

Conversation

@dmjio
Copy link
Copy Markdown
Owner

@dmjio dmjio commented May 3, 2025

This allows us to generate component names on user's behalf when they do not need inter-component communication.

  • Add global IORef of component IDs, w/ fresh component Id
  • If user doesn't give an ID, then generate one from the global ref
  • Add component_ smart constructor
  • setBodyComponent -> setComponent
  • Update documentation, removed old comments
  • ensure this works with the delegator
div_ [] [ embed (component_ app) ]

This allows us to generate component names on user's behalf when they
do no need inter component communication.

- Add global IORef of component IDs, w/ fresh component Id
- If user doesn't give an ID, then generator one from the global ref
- Add component_ smart constructor
- Update documentation, removed old comments
@dmjio dmjio force-pushed the nameless-components branch from afd2efc to 63532b5 Compare May 3, 2025 02:10
Comment thread src/Miso/FFI/Internal.hs Outdated
Comment thread src/Miso/Internal.hs
Comment thread src/Miso/Types.hs Outdated
Comment thread src/Miso/Types.hs Outdated
Comment thread src/Miso/Types.hs Outdated
dmjio and others added 13 commits May 3, 2025 02:17
Co-authored-by: Jan Hrcek <2716069+jhrcek@users.noreply.github.com>
Co-authored-by: Jan Hrcek <2716069+jhrcek@users.noreply.github.com>
Co-authored-by: Jan Hrcek <2716069+jhrcek@users.noreply.github.com>
Co-authored-by: Jan Hrcek <2716069+jhrcek@users.noreply.github.com>
Now that components are here, we must keep events from bubbling up out
of their respective sub trees into the parent sub tree.
- If a Component is named by a user (not auto-generated) we can use
that as a stable name during diffing. Otherwise, user's must rely on
key_ (via embedKeyed) as a stable name for Component replacement.
@dmjio
Copy link
Copy Markdown
Owner Author

dmjio commented May 3, 2025

A "nameless component" is a Component that is isolated from receiving communication with outside world (no other Component can send a message to it, but it can send a message to other named components). This is convenient for things like a progress bar that don't need naming and won't necessarily be replaced by other Component.

Normally when diffing, we can just replace two nodes if they have different tags, types, keys or data-component-id. Or if we're diffing against null we know to create or delete a node.

Now, if we allow users to omit the data-component-id (ala "nameless components"), and instead we generate it for them, the data-component-id no longer becomes a reliable indicator of diffing (since we generate fresh names on each call to runView for nested Component). This is because we now no longer can tell if a component changed its ID intentionally through view_ generation, or if it's a placeholder ID that we have generated for the user. Furthermore, a wrench 🔧 is thrown because you can replace a named component with a nameless one (and vice versa).

So here's what I think might be best. Since Component shouldn't be high traffic (they shouldn't be moving around the DOM much once they get mounted). We can just tell users that if they plan on replacing Component (specifically with other nameless Component), they have to rely on "key" as a stable name to do so (again only in the case of nameless components (i.e. component_) that are being replaced by other components -- when using a named component (component) we /can/ rely on that name as being stable on diff on it, use it for replacement).

I added a test w/ Component replacement diffing that relied on "key" and it has passed (so we keep dom.spec.ts 💯 ). We've added some manual testing to the component example for Component replace diffing in the Haskell layer.

But the tldr; is that we're going to have to tell users that if they think it's possible their Component will be replaced by another component (when using nameless components), they should give it a "key" (use embedKeyed_ - same w/ nameless components). Otherwise, if you only expect your Component to get created, deleted, replaced by text or node and not replaced by another Component, then you can safely ignore the key, when in doubt use key_.

This is an edge case, and it most likely won't happen often, when in doubt, name your components (use component), if you like to live (somewhat) dangerously, use component_ but make sure you don't replace it w/ another component in-place, unless you specify a key via embedKeyed. This is a remote edge case possibility users should be aware of

dmjio added 3 commits May 3, 2025 16:12
- If we have a 'vcomp', 'data-component-id' will always be set.
@dmjio dmjio merged commit ee1d042 into master May 3, 2025
3 checks passed
@dmjio dmjio deleted the nameless-components branch May 4, 2025 17:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants