Skip to content

"Maximum call stack size exceeded" when using v-show on a component using transition as root element #5353

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

Closed
schnuet opened this issue Feb 2, 2022 · 3 comments · Fixed by #5358
Labels
🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. 🐞 bug Something isn't working

Comments

@schnuet
Copy link

schnuet commented Feb 2, 2022

Version

3.2.29

Reproduction link

sfc.vuejs.org/

Steps to reproduce

  1. Open the repro.
  2. Wait. (up to 3 minutes)

What is expected?

The code should run indefinitely, without warnings.

What is actually happening?

After (around) three minutes, the console is flooded with "Maximum call stack size exceeded" errors and the browser slows down to a crawl. This gets worse the longer the page is left open.


I had refactored a lot of my code to use embedded transitions in components and forgot remove one place where I used v-show instead of the new "visible" prop. That crashed my app after a while.

@lidlanca
Copy link
Contributor

lidlanca commented Feb 2, 2022

rawSlot after an update will already be normalized.
resulting in a normalized slot function being normalized over and over.

with enough updates calling the normalized slot will reach the max stack size

const normalizeSlot = (
key: string,
rawSlot: Function,
ctx: ComponentInternalInstance | null | undefined
): Slot => {
const normalized = withCtx((...args: any[]) => {
if (__DEV__ && currentInstance) {
warn(
`Slot "${key}" invoked outside of the render function: ` +
`this will not track dependencies used in the slot. ` +
`Invoke the slot function inside the render function instead.`
)
}
return normalizeSlotValue(rawSlot(...args))
}, ctx) as Slot
// NOT a compiled slot
;(normalized as ContextualRenderFn)._c = false
return normalized
}

this patch will fix this bug, but perhaps there might be an higher level fix.

const normalizeSlot = (key, rawSlot, ctx) => {

    if(rawSlot && rawSlot._c === false) {
        // already normalized  
        return rawSlot 
    }
    const normalized = withCtx((...args) => {
     ...
    }, ctx);
    normalized._c = false;
    return normalized;
};

@edison1105 edison1105 added 🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. 🐞 bug Something isn't working labels Feb 3, 2022
@edison1105
Copy link
Member

edison1105 commented Feb 3, 2022

@lidlanca
should be

if(rawSlot._n) {
	// already normalized  
	 return rawSlot 
}

@lidlanca
Copy link
Contributor

lidlanca commented Feb 3, 2022

@edison1105

nice, so withCtx actually adds the _n marking, I missed that.

// mark normalized to avoid duplicated wrapping
renderFnWithContext._n = true

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. 🐞 bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants