Search code examples
javascriptsveltesvelte-3

Svelte - watch changes to component property outside the component (accessors)


Is it possible to watch changes to a component property outside the component?

I have tried using the $: declaration but it does not seem to work (except for the first time - detecting when the component is mounted).

I.e. this is the component which property changes from the inside

<script>
  export let title = 'Settings';

  setTimeout(() => {
    title = 'Settings - Test';
  }, 2000);

//
</script>

<svelte:options accessors={true}/>

and the component that includes it:

<script>
    import SettingsPage from './Settings.svelte';
    
    let page;   
    let title = '';
    
    $: {
        if (typeof page !== 'undefined') {
            title = page.title;
        }
    }
    
    $: title2 = typeof page !== 'undefined' ? page.title : '';
        
</script>

After 2 seconds, the titles should change to "Settings - test" (it does not work).

<h3>title: {title}</h3>
<h3>title2: {title2}</h3>

<div class="Page">
  <svelte:component this={SettingsPage} bind:this={page} />
</div>

Playground: https://svelte.dev/repl/91ef762b9f414223835fc1f08f20bd5d?version=3.42.2

Unfortunately the reactive declaration does not fire on this instance. Is there a way to make this work purely with regular properties? (I know there are workarounds, such as using a store as the property - but I would like to just have it as regular prop if possible).


Solution

  • In svelte you can easily bind a component's prop like title for the SettingsPage component by using <SettingsPage bind:title={title} />. By updating the title prop in the component it will also update the value of its parent.

    Have a look at the REPL.