在Svelte中,我可以跳过第一次挂载时的副作用钩子吗?

前端开发 2026-07-11

如何跳过在一个{@attach}钩子中的第一次$effect调用?

我尝试这样做,我认为应该可行:

<script>
    let count = $state(0);
</script>

<button onclick={() => count += 1}>
    clicks: {count}
</button>

<div
    {@attach div => {
        let firstRun = true;
        $effect(() => {
            if (firstRun) {
                firstRun = false;
                return;
            }
            div.innerText = count * 2;
        })
    }}>

</div>

但它没有识别对firstRun的改动,结果卡在提前退出的阶段。

说实话,在我看来这像是Svelte的一个bug,但我需要绕过它。

如果我进行一些改动并把firstRun设为一个状态,那么就能绕过它。

<script>
    import { untrack } from "svelte"
    let count = $state(0);
</script>

<button onclick={() => count += 1}>
    clicks: {count}
</button>

<div
    {@attach div => {
        let firstRun = $state(true);
        $effect(() => {
            if (firstRun) {
                console.log("first")
                untrack(() => firstRun = false);
                return;
            }
            console.log("not first")
            div.innerText = count * 2;
        })
    }}>

</div>

然而它在挂载时会执行两次,即使我已经取消对firstRun的跟踪。

有没有办法绕过这个?

解决方案

副作用的依赖跟踪是动态的,因此如果在退出一个副作用时没有读取到任何信号,它将再也不会执行。

这应该可行:

{@attach div => {
    let firstRun = true;
    $effect(() => {
        count; // track count
        if (firstRun) {
            firstRun = false;
            return;
        }

        div.innerText = count * 2;
    })
}}
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章