You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have a Modal Component that provides the style of Modal, content slot, and methods to open and close Modal.
The control method of opening and closing is implemented through the state of current,and current is set to undefiend when closing.
When calling this component, if there are child components within chilren, and first-level child component has an $effect, and second-level child component calls the clse methods, an exception whill be thrown.
Uncaught TypeError: Cannot read properties of undefined (reading 'model')
I have a #if check for the data usage, but the error still occurs. I suspect that the child components'rerendering executes earlier than the #if check.
test.svelte.ts(data model):
type State = 'init' | 'submitted';
export function createModal() {
let state = $state<State>('init');
return {
get state() {
return state;
},
submit() {
state = 'submitted';
}
};
}
export type Model = ReturnType<typeof createModal>;
Modal.svelte:
<script lang="ts" module>
let current = $state<{ model: Model }>();
export function open(model: Model) {
current = {
model
};
}
export function close() {
current = undefined;
}
</script>
<script lang="ts">
import { onDestroy, type Snippet } from 'svelte';
import type { Model } from './test.svelte';
let {
children
}: {
children: Snippet<[Model]>;
} = $props();
onDestroy(() => {
console.log('destroy test');
});
</script>
{#if current?.model}
{@render children(current.model)}
{/if}
+page.svelte
<script>
import { createModal } from './test.svelte';
import TestChildren1 from './TestChildren1.svelte';
import TestComponent, { open } from './Modal.svelte';
const model = createModal();
$effect(() => {
console.log('model', model);
});
</script>
<button
onclick={() => {
open(model);
}}>open</button
>
<TestComponent>
{#snippet children(model)}
<TestChildren1 {model} />
{/snippet}
</TestComponent>
TestChildren1:
<script lang="ts">
import { onDestroy } from 'svelte';
import TestChildren2 from './TestChildren2.svelte';
import type { Model } from './test.svelte';
let {
model
}: {
model: Model;
} = $props();
$effect(() => {
console.log('b', JSON.stringify(model));
});
onDestroy(() => {
console.log('destroy component 1');
});
</script>
<span>{model.state}</span>
<TestChildren2 {model} />
TestChildren2:
<script lang="ts">
import { onDestroy } from 'svelte';
import { close } from './Modal.svelte';
import type { Model } from './test.svelte';
let {
model
}: {
model: Model;
} = $props();
$effect(() => {
if (model.state === 'submitted') close();
});
setTimeout(() => {
model.submit();
}, 1000);
onDestroy(() => {
console.log('destroy component 2');
});
</script>
<span>{model.state}</span>
chunk-ZPWZ3TV6.js?v=a4869f9a:1549 Uncaught TypeError: Cannot read properties of undefined (reading 'model')
in$effectin TestChildren1.svelte
in Modal.svelte
in +page.svelte
in +layout.svelte
in root.svelte
at Modal.svelte:29:27
at get model (+page.svelte:19:26)
at $effect (TestChildren1.svelte:13:34)
(匿名) @ Modal.svelte:29
get model @ +page.svelte:19
$effect @ TestChildren1.svelte:13
setTimeout
TestChildren2 @ TestChildren2.svelte:16
TestChildren1 @ TestChildren1.svelte:18
(匿名) @ +page.svelte:19
consequent @ Modal.svelte:25
(匿名) @ Modal.svelte:28
Severity
blocking an upgrade
The text was updated successfully, but these errors were encountered:
It seems that the effect inside TestChildren2.svelte does kick off the chain that leads to the error. It closes the modal, and then the render tag inside Modal.svelte is executed even though it shouldn't be because the surrounding if should've already made it falsy.
It seems that the effect inside TestChildren2.svelte does kick off the chain that leads to the error. It closes the modal, and then the render tag inside Modal.svelte is executed even though it shouldn't be because the surrounding if should've already made it falsy.
This problem only occurs when TestChildren2 uses $effect. The same applies when using $inspect.
Uh oh!
There was an error while loading. Please reload this page.
Describe the bug
I have a Modal Component that provides the style of Modal, content slot, and methods to open and close Modal.
The control method of opening and closing is implemented through the state of current,and current is set to
undefiend
when closing.When calling this component, if there are child components within chilren, and first-level child component has an $effect, and second-level child component calls the clse methods, an exception whill be thrown.
I have a
#if
check for the data usage, but the error still occurs. I suspect that the child components'rerendering executes earlier than the#if
check.test.svelte.ts(data model):
Modal.svelte:
+page.svelte
TestChildren1:
TestChildren2:
Reproduction
example:https://github.com/Sincenir/svelte-issues-effect-and-modal
localhost... /test2
Logs
System Info
Severity
blocking an upgrade
The text was updated successfully, but these errors were encountered: