Preventing Svelte component parameter reactivity

1.4k views Asked by At

I've written a modal component in Svelte that has multiple exported variables for controlling behavior. The values of these variables can vary from invocation to invocation, but once a modal is showing, the only value that can be expected to change is that of isOpen. This suggests that isOpen is the only variable requiring reactivity, but if my understanding is correct, the presence of other variables in the HTML will cause Svelte to unnecessarily generate reactive code for all those variables too, unnecessarily fattening the code base.

My question is, what strategies are available for preventing reactive code from being generated for component parameters when it is not needed?

In the following, message will not change while the modal is displayed, so it seems that only isOpen need be reactive. The Svelte compiler cannot know this, though, so I have to explicitly do something that inhibits this reactive behavior.

<script lang="ts">
  import { closeModal } from 'svelte-modals';

  export let isOpen: boolean;
  export let message: string;
</script>

{#if isOpen}
  <div class="contents">
    <p>{message}</p>
    <button on:click={closeModal}>OK</button>
  </div>
{/if}

The only technique I'm aware of is to move the variable out into a function, as follows:

<script lang="ts">
  import { closeModal } from 'svelte-modals';

  export let isOpen: boolean;
  export let message: string;
  
  const getMessage = () => message;
</script>

{#if isOpen}
  <div class="contents">
    <p>{getMessage()}</p>
    <button on:click={closeModal}>OK</button>
  </div>
{/if}

Is there a more succinct or more conventional way to accomplish this? For a technology so well thought out as Svelte, I find myself believing that there has to be a less clunky way to do this. A person who comes along to maintain code after me might see this as unnecessarily verbose and eliminate the indirection, unwittingly fattening up the code base (should they do this wholesale). It seems like there ought to be something more explicit.

Or perhaps there is a way to require that all reactive variables be explicitly designated, such as with a preceding $:?

1

There are 1 answers

4
alexvdvalk On BEST ANSWER

You could assign the message to a local variable when the component is initialized.

<script>
    export let message;
    export let isOpen =true;
    const originalMessage=message;
</script>

<div>
    Message: {originalMessage}
</div>
<div>
    isOpen: {isOpen}
</div>