Skip to content

docs: clarify when attachments re-run #15927

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

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

Rich-Harris
Copy link
Member

No description provided.

Copy link

changeset-bot bot commented May 15, 2025

⚠️ No Changeset found

Latest commit: e4ee271

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@svelte-docs-bot
Copy link

Copy link
Contributor

Playground

pnpm add https://pkg.pr.new/svelte@15927

@@ -55,7 +57,7 @@ A useful pattern is for a function, such as `tooltip` in this example, to _retur
</button>
```

Since the `tooltip(content)` expression runs inside an [effect]($effect), the attachment will be destroyed and recreated whenever `content` changes.
Since the `tooltip(content)` expression runs inside an [effect]($effect), the attachment will be destroyed and recreated whenever `content` changes. The same thing would happen for any state read _inside_ the attachment function when it first runs.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good clarification, but I think we also should have a code example showing how to do it if that's not what you want.

Suggested change
Since the `tooltip(content)` expression runs inside an [effect]($effect), the attachment will be destroyed and recreated whenever `content` changes. The same thing would happen for any state read _inside_ the attachment function when it first runs.
Since the `tooltip(content)` expression runs inside an [effect]($effect), the attachment will be destroyed and recreated whenever `content` changes. The same thing would happen for any state read _inside_ the attachment function when it first runs.
In case this is not the desired behavior, and you instead want the attachment to only be executed once on mount, then make sure to not read state eagerly inside the function body. Assuming `tippy` would be very expensive to setup and tear down (which it isn't), then you could rewrite the above example by passing a reference to the `content` variable and invoke it inside a nested effect:
```svelte
<!--- file: App.svelte --->
<script>
import tippy from 'tippy.js';
let content = $state('Hello!');
/**
* @param {() => string} content
* @returns {import('svelte/attachments').Attachment}
*/
function tooltip(content) {
return (element) => {
const tooltip = tippy(element);
$effect(() => {
tippy.setContent(content());
});
return tooltip.destroy;
};
}
</script>
<input bind:value={content} />
<button {@attach tooltip(() => content)}>
Hover me
</button>
```

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is probably a niche enough thing that we could move it to a separate 'Controlling when attachments re-run' section further down — thoughts?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fine with me, I just want to have it mentioned somewhere

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants