-
Notifications
You must be signed in to change notification settings - Fork 951
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
"No component for CID" error because of duplicate live components #3650
Comments
Thanks for the quick response!
Edit: I just realized that the JS is incorrectly loaded when I change to |
We have an example that uses the bundled JS linked in our issue template: https://github.com/phoenixframework/phoenix_live_view/blob/main/.github/single-file-samples/main.exs :) |
Thanks! I've updated the example to use this template and I can still reproduce it. |
Thank you! I'm at my computer now and can reproduce it with your example. I'm working on another bug at the moment, but I'll look into this in detail soon! |
…Views Adds a check for duplicate LiveComponents (Fixes #3650).
@dvic this is tricky, because neither on the server, nor on the client we can easily detect the case when the duplicate LiveComponent is created during an update. The following happens: Initially, the page looks like this:
Then, it is updated to
The problem here is that unchanged trees ignored for such updates, therefore LiveView doesn't know that the component "A" was already rendered in "0_A", because the update only affects "1_A". We have a similar issue on the client, where we skip unchanged trees when patching. Finally, morphdom patches the DOM and moves the duplicate child to the new position. The best thing we can do is detect this in LiveViewTest. I've opened #3653 which will fail when testing like this:
|
I see, thanks for looking into it! However, I have one question:
Just to double check: then the markup in the old position is removed right? (that's what I'm seeing in the example in this issue) Is it maybe worth considering to allow live components to be rendered in two positions? I somehow always thought a live component is rendered twice on the page if it has the same id 🙈 https://hexdocs.pm/phoenix_live_view/Phoenix.LiveComponent.html currently mentions You must always pass the module and id attributes. The id will be available as an assign and it must be used to uniquely identify the component. All other attributes will be available as assigns inside the LiveComponent.
👍 |
Yes! When we patch the DOM the following happens: <div id="0_A" data-phx-id="c1-phx-GB2rSZ9ucjX8AgAG" data-phx-component="1" data-phx-skip></div>
<div data-phx-id="c2-phx-GB2rSZ9ucjX8AgAG" data-phx-component="2" id="0_B">
<div id="A" data-phx-id="c3-phx-GB2rSZ9ucjX8AgAG" data-phx-component="3" data-phx-skip></div>
</div> The first component is skipped (
I don't think this is something we want to do. Can you think of any use cases that would require this? If you try to render a live component with the same id twice on the page and this happens in the same render, you'll already get a warning:
This has actually been the case since LV 0.5.0, see d5c4368. |
* allow to configure if detected errors raise or warn when testing LiveViews Adds a check for duplicate LiveComponents (Fixes #3650). * test duplicate id / component errors
Environment
Actual behavior
If you have nested live components with the same ID on the page, no backend error is thrown but you get "No component for CID" after a few interactions.
Expected behavior
I expected to get
found duplicate ID "A" for component Example.LiveComp when rendering template
in the reproducible example below.I do get this if I change this line:
<.live_component :for={{child, index} <- Enum.with_index(@children)} module={Example.LiveComp} id={"#{index}_#{child.id}"} child_id={child.id} children={child.children} />
to
<.live_component :for={{child, index} <- Enum.with_index(@children)} module={Example.LiveComp} id={child.id} child_id={child.id} children={child.children} />
So it seems the duplicate detection doesn't check the complete tree?
Reproducible example
Click twice on
Open Child A
(top to bottom) and then twiceClose
(from bottom to top).The console shows no component for CID 2.
The text was updated successfully, but these errors were encountered: