Home > Web Front-end > JS Tutorial > 'Helper' Varaibles in Svelte 5

'Helper' Varaibles in Svelte 5

DDD
Release: 2024-11-10 08:28:02
Original
949 people have browsed it

Helper Varaibles in Svelte 5

Bye Bye Magical Svelte 4 $:

Following my recent post Experiences and Caveats of Svelte 5 Migration I would like to highlight some techniques and change of mindset when going from Svelte 4 to Svelte 5.

Svelte 4 uses "magical" $: and let and does all the heavy lifting to make code reactive. We also embraced varaibles reassignment like

<script>
let arr = [1, 2, 3]
let value = 4

arr = [...arr, value]
</script>
Copy after login

instead of methods updating/mutating varaibles like push etc.

I was quite suprprised to re-learn good old JS patterns using Svelte 5.

No Needd to Be Reactive All the Time

And I was also probably quite spoiled by let in Svelte 4 , no reasoning about reactivity, it was included if needed. But not all varaibles have to be reactive. Also non reactive variables may be updated in reactive or even "traditional mutating code". The real need for reactive variable is when we use it in UI (when this varaible is rendered in html/page and we need it to update later).

You may encounter erros in Svelte 5 like Cannot assign to derived state, State referenced in its own scope will never update. Did you mean to reference it inside a closure? or derived_references_selfnA derived value cannot reference itself recursively if using Svelte 4 coding style.

Example of Helper Variables

Take a look at this example of Svelte 4 style of code:

<script>
    let value;
    let derivedArr = []

    $: if (value) {
        derivedArr = [...derivedArr, value]
    }

    function random () {
        value = Math.floor(1 + Math.random() * 10)
    }
</script>

<button on:click="{random}">Generate Random Value</button>
<p>value: {value}</p>
<p>derivedArr: {derivedArr}</p>
Copy after login

DEMO

We have two reactive variables and Svelte 4 solves the updates automatically. We only needed to remember that the right way is by reassigning the variable.

In Svelte 5 we should think a little how to achieve the same result. The two variables we are using are not enough, we need one more, the helper one.

Prefered way is to use a $derived() rune.

<script>
    let value = $state();
    let helperArr = [];

    let derivedArr = $derived.by(() => {
      if (value) {
                helperArr.push(value);
                return helperArr;
        }
    });

    function random () {
        value = Math.floor(1 + Math.random() * 10)
    }
</script>

<button onclick="{random}">Generate Random Value</button>
<p>value: {value}</p>
<p>derivedArr: {derivedArr}</p>
Copy after login

DEMO

If you know easier way to do this let me know.

There is also an $effect() rune way to achieve the same. It might look even simplier but we should avoid effects if possible (mainly Svetlet 5 effects do not run on the server/SSR).

<script>
    let value = $state();
    let helperArr = []
    let effectArr = $derived(helperArr);

    $effect.pre(() => {
            if (value) {
              helperArr.push(value)
            }
        })

    function random () {
        value = Math.floor(1 + Math.random() * 10)
    }
</script>

<button onclick="{random}">Generate Random Value</button>
<p>value: {value}</p>
<p>effectArr: {effectArr}</p>
Copy after login

DEMO

Real Life Example

This is the example how I tried to migrate quite stright forward Svelte 4 page to Svelte 5. It took me a while to rethink the code. This page works as a posts search with a "Load More" functionality (adding results or pagging if a user does not have JS):

Svelte 4

<script>
    import Icon from '../components/Icon.svelte';
    import { enhance } from '$app/forms';
    import { tick } from 'svelte';

    export let form;
    export let searchingLang;
    export let l;

    let results = [];
    let previousSearch = '';
    let searchTerm;
    let skip;

    $: if (!!form && form?.thereIsMore) {
        searchTerm = form.searchTerm;
        skip = Number(form?.skip)   20;
    }

    $: if (!!form?.searchResultFromAction) {
        if (previousSearch == form.searchTerm && form.thereWasMore) {
            results = [...results, ...form.searchResultFromAction];
        } else {
            results = [...form.searchResultFromAction];
            previousSearch = form.searchTerm;
        }
    }

    async function intoView(el) {
        await tick();
        if (el.attributes.index.nodeValue == skip - 20 && skip != undefined) {
            el.scrollIntoView({ behavior: 'smooth' });
        }
    }
</script>

{#if results.length}
    <ol>
        {#each results as item, index}
            <li use:intoview aria-posinset="{index}">
                <!-- users without javascript have calculated order of results within paggination and css disables standard ol ul numbering -->
                <!-- users with javascript have standard ol ul numbering and loading more feature -->
                <noscript>{Number(index)   1   Number(form?.skip)}. </noscript>
                <a href="/act/%7BsearchingLang%7D/%7Bitem.id%7D/present/text">{item.title}</a>
            </li>
        {/each}
    </ol>

    {#if form?.thereIsMore}
        
Copy after login

The above is the detailed content of 'Helper' Varaibles in Svelte 5. For more information, please follow other related articles on the PHP Chinese website!

source:dev.to
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template