Skip to content

Unexpected behavior when combining spread operator with createAttachmentKey #15949

Closed
@Jimdooz

Description

@Jimdooz

Describe the bug

When using the spread operator {...obj} to apply an object containing a property created with createAttachmentKey() to an element, the attachment is destroyed and recreated on every component re-render, even for unrelated state changes.

This behavior differs from directly using the @attach directive, where the attachment is properly maintained across re-renders.

Reproduction

<script>
    import { createAttachmentKey } from "svelte/attachments";

    function element() {
        let value = $state(false);

        const root = {
            [createAttachmentKey()]: () => {
                console.log("attached");

                return () => {
                    console.log("detached");
                }
            }
        };

        return {
            root,
            get value() { return value },
            set value(v) { value = v }
        }
    }

    const elem = element();
</script>

<div {...elem.root} {@attach () => {
    console.log("local attached");
    return () => {
        console.log("local detached");
    }
}}>
    <p>Value: {elem.value}</p>
</div>

<button onclick={() => elem.value = !elem.value}>Toggle</button>

Click multiple time on button, and check console

Expecting result

attached
local attached
*click*
*click*
*click*

Result obtained

attached
local attached
*click*
detached
attached
*click*
detached
attached
*click*
detached
attached

Logs

System Info

System:
    OS: Windows 11 10.0.26100
    CPU: (12) x64 Intel(R) Core(TM) i7-8700K CPU @ 3.70GHz
    Memory: 5.18 GB / 15.94 GB
  Binaries:
    Node: 22.12.0 - C:\Program Files\nodejs\node.EXE
    npm: 11.0.0 - C:\Program Files\nodejs\npm.CMD
    pnpm: 9.14.2 - ~\AppData\Local\pnpm\pnpm.EXE
  Browsers:
    Edge: Chromium (132.0.2957.127)
    Internet Explorer: 11.0.26100.1882

Severity

annoyance

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions