3

I stuck a bit with a problem:

I have a svelte component, which works with a number of props:

<script>
    export let foo;
    export let bar;

</script>

But also, I'd like to pass some props to my HTML element directly. So my solution is:

<script>
    export let foo;
    export let bar;

    const {
        foo,
        bar,
        ...other
    } = $$props;
</script>

<button {...other}>
    Some action
</button>

This one has a huge problem: When I change some props like "class", the component wouldn't be updated.

<MyComponent {foo} {bar} class={condition ? 'one' : 'two'} />

What is a better way to solve this case? I mean, I have to support different props, not only "class" one. How could I pass the rest of the props to an HTML-element

1 Answer 1

6

Well... Passing class this way does work for me. See this REPL.

App.svelte

<script>
    import MyComponent from './MyComponent.svelte'
    
    let checked
</script>

<label>
  <input type=checkbox bind:checked />
    Blue?
</label>

<MyComponent class={checked ? 'blue' : 'red'} />

MyComponent.svelte

<script>
  export let foo
  export let bar
</script>

<pre>foo={foo} bar={bar}</pre>

<button {...$$restProps}>
  Some button
</button>

<style>
    :global(.red) {
        color: red;
    }
    :global(.blue) {
        color: blue;
    }
</style>

A couple notes...

Svelte has quite recently introduced $$restProps (docs -- end of the section), which might be better suited that filtering props manually.

This block of code in your example is not reactive:

    const {
        foo,
        bar,
        ...other
    } = $$props;

It is only executed once when the component is created. It is not updated when props change, which might explain why your subsequent change of props (class={condition ? 'one' : 'two'}) is not reflected.

If you need to do something like this (say because you need more control than what $$restProps offers out of the box), you need to put this in a reactive block ($:).

For example:

$: ({ foo, bar, ...other } = $$props)

The above JS syntax is equivalent to the following, more verbose, alternative:

let foo
let bar
$: {
  foo = $$props.foo
  bar = $$props.bar
}
Sign up to request clarification or add additional context in comments.

1 Comment

Oh, that's nice! I didn't know $$restProps exists.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.