Open Freeskier opened 3 weeks ago
Can't you just call empty
directly from within the component?
@paoloricciuti it's just a quick demo to show you what I meant.
In my real scenario, from the child component on the specific action I need to pass the reference. A very short example below:
store.svelte.js
let refs = $state([]);
export function createStore() {
return {
get refs() {
return refs;
},
addRef: (ref) => refs.push(ref);
}
Component.svelte
<script>
const store = createStore()
export function foo() {
alert('foo');
}
</script>
<button onclick:{()=> store.addRef(***HERE I NEED REFERENCE***) }>clickme</button>
AnotherComponent.svelte
<- This one exist somewhere, its not the direct parent of the Component.svelte
<script>
// on some action I want to be able to call empty() function from refs
const store = createStore()
store.refs.forEach(r => r.empty())
</script>
I think it would be easier to have each component add its own empty
function to the list of refs when they're instantiated.
Probably a module
level scope that is available to all instances of a component via <script module>
https://svelte.dev/docs/svelte/svelte-files#script-module might be the most pretty straightforward way of doing it but yeah, you can also import an external store in the module or in the instance.
Here's a quick demo that I created. I also added a on-destroy effect to remove the empty ref from the "store".
If the functionality is more complex than just a function, you end up essentially rebuilding the instance's API by hand. I also could have used a functionality like this when orchestrating between complex components via a context; had to wrap a bunch of properties in accessors and pass all relevant functions manually.
Would vote for a $this
or getCurrentComponent()
function (which existed before in a different form as part of the internal APIs).
@brunnerh yeah, $this
makes sense, because it refers to bind:this
.
@Leonidaz Thank you for the demo, of course there are workarounds as you presented. I just mentioned about this feature here just because it'd make life easier :)
Things like $this
and getCurrentComponent
are complicated to implement in Svelte 5. That's because components aren't instances and are instead functions, so when you reference them, you're actually just taking the object they return when called. As such, I don't think there's an elegant way of implementing such things without incurring overhead for users that don't use these features. Not to mention that we probably want to avoid adding any more runes right now for things that have work-arounds, even they are cumbersome.
Things like
$this
andgetCurrentComponent
are complicated to implement in Svelte 5. That's because components aren't instances and are instead functions, so when you reference them, you're actually just taking the object they return when called. As such, I don't think there's an elegant way of implementing such things without incurring overhead for users that don't use these features. Not to mention that we probably want to avoid adding any more runes right now for things that have work-arounds, even they are cumbersome.
I wonder if we could add an exports variable in the compiler code, we add stuff to that variable and then we return that variable and when people call $this() we just access that variable. But that's just a random thought
@paoloricciuti Maybe, but it gets complicated around components that have accessors enabled as they're added as getters/setters.
Things like
$this
andgetCurrentComponent
are complicated to implement in Svelte 5. That's because components aren't instances and are instead functions, so when you reference them, you're actually just taking the object they return when called. As such, I don't think there's an elegant way of implementing such things without incurring overhead for users that don't use these features. Not to mention that we probably want to avoid adding any more runes right now for things that have work-arounds, even they are cumbersome.
@trueadm I'm not sure about my idea (i tried to take a look into svelte lib but its quite hard), but if components are in fact functions, can't it be done by taking a reference of it and pass down as a "hidden" prop that can be accessed?
@Freeskier bind:this
uses to the object that is returned from the component function. If you look on the playground at the compiled output, it should make more sense. That's how it's got to work, we can't change that mechanic without breaking everyones app that uses bind:this
on components today.
Describe the problem
In my project I needed a self instance of the component itself. What I mean by that I will provide in an example below. From the docs:
App.svelte
ShoppingCart.svelte
This is a valid code and you can store the reference of
ShoppingCart
in the parent component.In my scenario, I needed to pass the same
cart
reference, but from inside of theShoppingCart
. Of course there is a workaround by storing and passing the reference as a props to the child component like below:App.svelte
ShoppingCart.svelte
Describe the proposed solution
I'm not that deep into the fundametals of the svelte, thats why I don't know if my proposition has any sense. But what about consider
$self()
rune?Importance
would make my life easier