If we have something like a Tooltip
class that needs to instantiate an instance, update that instance, and destroy that instance in sync with when the component is mounted, updated, and destroyed (as demonstrated in the code below), there seems to be two patterns for doing this.
use:action
onMount
and onDestroy
The use:action
method seems cleaner, but aside from that, are there any underlying differences between these two methods that would make one preferred over the other in certain situations?
Example of using use:action
:
<script>
import Tooltip from './tooltip'
export let text = ''
function initTooltip(node, text) {
const tooltip = Tooltip(node)
tooltip.text = text
return {
update(text) {
tooltip.text = text
},
destroy() {
tooltip.destroy()
}
}
}
</script>
<div use:initTooltip={text}>
<slot></slot>
</div>
Example of using onMount
and onDestroy
:
<script>
import Tooltip from './tooltip'
import { onMount, onDestroy } from 'svelte'
export let text = ''
let node
let tooltip
onMount(() => {
tooltip = Tooltip(node)
tooltip.text = text
})
$: if (tooltip && tooltip.text !== text) {
tooltip.text = text
}
onDestroy(() => {
if (tooltip) {
tooltip.destroy()
}
})
</script>
<div bind:this={node}>
<slot></slot>
</div>
If it's behaviour that you can imagine needing to reuse among multiple components, or if it's something that you can imagine applying to an element inside an {#if ...}
block (for example), then it probably belongs in an action.
It it's something that 'belongs' to the component itself, rather than a specific element, then it's probably more of a lifecycle thing.
In this case, my tendency would probably be to use an action.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With