Subscribe on changes!

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

avatar
Dec 28th 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

avatar
Dec 28th 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.

avatar
Dec 28th 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.

avatar
Dec 28th 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.

avatar
Dec 28th 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?