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

When KeepAlive caches more items than its max prop allows, reactivated components may be erroneously marked as being unmounted #7355

Closed
funkyvisions opened this issue Dec 15, 2022 · 7 comments
Labels
🐞 bug Something isn't working scope: keep-alive

Comments

@funkyvisions
Copy link

Vue version

3.2.45

Link to minimal reproduction

https://codesandbox.io/s/emit-issue-kezqfe

Steps to reproduce

Follow directions on reproduction site.

Click on "Create new page". Then click on the button in the blue box. Notice that it responds by showing "Clicked".
Do this 4 more times so that there are 5 pages (make sure you do the final click).
Now click on "Render page 4". Notice the click event does not get emitted all the way to the onClicked handler in Page.vue.
Click on "Render page 3" and the button works again.

What is expected?

emit should work

What is actually happening?

emit does not work

System Info

System:
    OS: macOS 12.6
    CPU: (12) x64 Intel(R) Core(TM) i7-8850H CPU @ 2.60GHz
    Memory: 20.04 MB / 32.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 16.13.1 - ~/.nvm/versions/node/v16.13.1/bin/node
    Yarn: 1.22.0 - /usr/local/bin/yarn
    npm: 8.1.2 - ~/.nvm/versions/node/v16.13.1/bin/npm
  Browsers:
    Chrome: 108.0.5359.98
    Edge: 108.0.1462.46
    Firefox: 106.0.3
    Safari: 16.2
  npmPackages:
    vue: 3.2.41 => 3.2.41

Any additional comments?

This was broken by this commit #5679. If I remove the 2 lines added

if (instance.isUnmounted)
    return;

then it works once again.

@LinusBorg
Copy link
Member

LinusBorg commented Dec 15, 2022

As this only happens when a keep-alive has more children than max allows do cache ... I think there's a different underlying problem, surfaced by the fix in #5679

Keep-Alive children when 5 children have been created:

Bildschirm­foto 2022-12-15 um 22 27 55

KeepAlive has 4 children. key=5 is active, key=4 is inactive

after switching to page 4:

Bildschirm­foto 2022-12-15 um 22 29 17

  • Page 4 is being shown in the browser
  • but it still shows as inactive in the devtools.

Logging that Page 4 component to the console, we see this:

Bildschirm­foto 2022-12-15 um 22 31 11

  • The component is marked as being deactivated (which it was previously, but shouldn't be anymore)
  • the component is also marked as being mounted and unmounted at the same time.

It's worth noting that this only happens when there are more items than the keep-alive's max attribute allows to be cached.

@LinusBorg LinusBorg added 🐞 bug Something isn't working scope: keep-alive labels Dec 15, 2022
@LinusBorg LinusBorg changed the title emit stops working in nested components within a keep-alive When KeepAlive caches more items than maxprop allows, reactivated components may be erroneously marked as being unmounted Dec 16, 2022
@LinusBorg LinusBorg changed the title When KeepAlive caches more items than maxprop allows, reactivated components may be erroneously marked as being unmounted When KeepAlive caches more items than its max prop allows, reactivated components may be erroneously marked as being unmounted Dec 16, 2022
@funkyvisions
Copy link
Author

Oh. So this sounds a little more serious then. My app is very dependent on being able to go over the max limit and relying on it purging things properly.

GRPdream added a commit to GRPdream/core that referenced this issue Jan 12, 2023
…ejs#7355)

keep-alive component status abnormal when cache items more than its max, after debugging, I found that its judge 2 VNode is same logic is wrong(as cached.type !== current.type).
@funkyvisions
Copy link
Author

funkyvisions commented Jan 16, 2023

@LinusBorg and @GRPdream I think this bit me again today in a different way. I'm seeing my watch function getting called for an inactive a disposed child of a keep-alive component. I put onActivated and onDeactivated handlers that set a flag in the component that has the watch and I see the watch getting called for an inactive disposed component. Ugh! I think I'm going to have to write my own composable that wraps watch in order to protect against this. I can write a separate code example of this if necessary, because I'm not 100% sure it's the same bug.

@LinusBorg
Copy link
Member

That's actually expected. Components are kept alive - so their reactive defects still works like normal, they are not "asleep" or anything. Just out of the DOM while deactivated.

It's left to you to customize this with the help of the(de)activated hooks

@funkyvisions
Copy link
Author

funkyvisions commented Jan 16, 2023

@LinusBorg Sorry, I didn't correctly state this above. This is a component that is no longer in the keep-alive tree. It was removed by maxSize. It doesn't show up as an inactive child in the Vue tools. It's supposed to be gone, yet the watch for it got called.

@LinusBorg
Copy link
Member

Okay that sounds different. Also different than your original issue, which is about reactivated components being unresponsive.

It may be related, or not.

@funkyvisions
Copy link
Author

@LinusBorg I'll try to work up an example. Thanks.

GRPdream added a commit to GRPdream/core that referenced this issue Feb 5, 2023
…ejs#7355)

keep-alive component status abnormal when cache items more than its max, after debugging, I found that its judge 2 VNode is same logic is wrong(as cached.type !== current.type).

Author:    李想 <945452469@qq.com>
zhangzhonghe pushed a commit to zhangzhonghe/core that referenced this issue Apr 12, 2023
IAmSSH pushed a commit to IAmSSH/core that referenced this issue May 14, 2023
@github-actions github-actions bot locked and limited conversation to collaborators Sep 15, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
🐞 bug Something isn't working scope: keep-alive
Projects
None yet
Development

No branches or pull requests

2 participants