Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass the props from grandchild to parent without exporting in svelte

I have a button component (grandchild) that has an exported prop (as follows)

<script>
    export let buttonText = "";
</script>

<button>
    {buttonText}
</button>

In the component I import this button. But I don't want to pass the data to the prop here.

<script>
import Button from './Button.svelte';
</script>

<h1>
    Hello from the component
    <br>
    <Button buttonText=""/>
</h1>

Note: that I have not exported the buttonText from the component

I want to call the component from the parent and pass the data to buttonText

<script>
    import Component from './Component.svelte'
</script>

<Component buttonText="Hello"/>

Can I do it without exporting?

The reason I wanted to do it, I have many subcomponents such as buttons, forms etc being imported into the component. I already some props exported from the component itself. By exporting the props of subcomponents, I would end up having a big mess of exports including duplication as well.

If this is not possible, is there any better way?

like image 942
jeff Avatar asked Oct 23 '25 08:10

jeff


2 Answers

You can use setContext to set or get data from a parent with setContext to a child or a child from a child et cetera with getContext. First the basics:

parent:

import { setContext } from "svelte"; 
    
let btnTxt = "Button Text";
setContext("getBtnTxt", btnTxt"}

grandchild

import { getContext } from "svelte";

let btnTxt = getContext("getBtnTxt")

But the are other ways to set and get data from the parent.

Example set and get parent data:

const ctxFilters = { a: false, b: false, c: false };
setContext("ctxFilters", {
  get filters() {
    return ctxFilters;
  },
  set filters(obj) {
    Object.assign(ctxFilters, obj);
  },
});

and in a child / childs or grandchilds:

const filterCtx = getContext("ctxFilters");
let filters = filterCtx.filters;  // use the getter
...
filterCtx.filters = filters;  // or use the setter

like image 64
voscausa Avatar answered Oct 25 '25 23:10

voscausa


you could use svelte slots for that like so:

grandchild

<button>
  <slot />
</button>

parent

<h1>
  Hello from the component
  <br />
  <Button>
    <slot name="btn-text" />
  </Button>
</h1>

grandparent

<Component>
  <svelte:fragment slot="btn-text">Hello</svelte:fragment>
</Component>
like image 21
Carlos Daniel Vilaseca Avatar answered Oct 25 '25 22:10

Carlos Daniel Vilaseca