Skip to content
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

Static Slots optimization combined with component instance re-use can lead to stale slot content never being updated. [EDGE CASE] #2893

Closed
Jokcy opened this issue Dec 28, 2020 · 4 comments · Fixed by #3523
Labels
🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. has workaround A workaround has been found to avoid the problem scope: slots

Comments

@Jokcy
Copy link
Contributor

Jokcy commented Dec 28, 2020

Version

3.0.4

Reproduction link

https://codesandbox.io/s/demo-for-sfc-slots-issue-n27kc

Steps to reproduce

You can see Hello never change to World.

I already find the reason is that SFC compiler add { _: 1 } to the compiled slots, which in updateSlots tell Vue there is no need to update instance.slots. But in this case, it work not correctly.

What is expected?

Hello and World switch in 1 second

What is actually happening?

never update

@LinusBorg
Copy link
Member

The cause is that the slots for each <A> are indeed stable and don't need updating, but Vue is re-using the same instance of A for efficiency when you toggle between the two vnodes.

Not sure we can fix this at the compiler level without de-optimizing the usually justified use-cases of keeping slots stable.

It can be corrected by applying a key to each instance of A:

<template>
  <B>
    <A key="A">Hello</A>
    <A key="B">World</A>
  </B>
</template>

You could also apply these keys to the vnodes within the render function of B, depending on your use case.

@Jokcy
Copy link
Contributor Author

Jokcy commented Dec 28, 2020

The cause is that the slots for each <A> are indeed stable and don't need updating, but Vue is re-using the same instance of A for efficiency when you toggle between the two vnodes.

Not sure we can fix this at the compiler level without de-optimizing the usually justified use-cases of keeping slots stable.

It can be corrected by applying a key to each instance of A:

<template>
  <B>
    <A key="A">Hello</A>
    <A key="B">World</A>
  </B>
</template>

You could also apply these keys to the vnodes within the render function of B, depending on your use case.

Yeah I know key will help to fix this. But I guess it's better to update this behavior because I spend 2-3 hours to find out why😂, it's really confusing when I face it.

@LinusBorg
Copy link
Member

LinusBorg commented Dec 28, 2020

Well I'm saying that at least I personally don't see how, as the problem you are facing here is not detectable by static analysis during compilation.

So the only way I can see would be to never optimize slots in this way, which is too high a price to solve such an edge case, in my opinion.

Maybe a better route would be to document the edge cases one can come across when manually manipulating slots content in render functions.

@posva posva added the has workaround A workaround has been found to avoid the problem label Dec 28, 2020
@Jokcy
Copy link
Contributor Author

Jokcy commented Dec 28, 2020

Yeah, if only edge case like this will face this issue, maybe a doc is enough. Can we find a way to warning when people manually manipulating slots content in render functions?

@LinusBorg LinusBorg changed the title slots never updated because the { _: 1 } optimization Static Slots optimization combined with component instance re-use can lead to stale slot content never being updated. Dec 29, 2020
@LinusBorg LinusBorg changed the title Static Slots optimization combined with component instance re-use can lead to stale slot content never being updated. Static Slots optimization combined with component instance re-use can lead to stale slot content never being updated. [EDGE CASE] Dec 29, 2020
@HcySunYang HcySunYang added the 🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. label Apr 1, 2021
yyx990803 pushed a commit that referenced this issue Apr 1, 2021
)

fix #2893

Manually rendering the optimized slots should allow subsequent updates to exit the optimization mode correctly
@github-actions github-actions bot locked and limited conversation to collaborators Oct 22, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. has workaround A workaround has been found to avoid the problem scope: slots
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants