Here is what I use in non-rune mode
<script lang="ts">
import { goto } from '$app/navigation';
export let data;
$: pageNum = data.selected.pageNum;
// Local state: sets to new option value from server when data changes
$: selectedSomeOption = data.selected.someOption;
function changeURL() {
goto(`/?pageNum=${encodeURIComponent(pageNum)}`);
}
</script>
<div class="w-screen h-screen flex items-center justify-center flex-col gap-4">
<div class="text-xl font-bold">
{selectedSomeOption} ({pageNum})
</div>
<div class="flex gap-2 items-center justify-center">
<button
class="border border-blue-500 p-2 rounded-lg text-blue-500"
on:click={() => {
selectedSomeOption = 'New Option value!';
}}
>
Change Option
</button>
<button
class="bg-blue-500 text-white p-2 rounded-lg"
on:click={() => {
pageNum += 5;
changeURL();
}}
>
+5
</button>
</div>
</div>
import type { PageServerLoad } from './$types';
export const load: PageServerLoad = ({ url }) => {
let pageNum = +(url.searchParams.get('pageNum') ?? 0);
if (pageNum > 10) {
pageNum = 0;
}
return {
selected: {
pageNum: pageNum,
someOption: `hello ${Math.floor(Math.random() * 100)}`
}
};
};
This is what I have tried with runes. Here the value is being set for data.selected.someOption
but that's not triggering a re-render.
The data.selected.pageNum
works just fine (But this is also does not trigger a re-render. It just apperas to work because of the goto
function call).
<script lang="ts">
import { goto } from '$app/navigation';
let { data } = $props();
function changeURL() {
goto(`/runes?pageNum=${encodeURIComponent(data.selected.pageNum)}`);
}
</script>
<div class="w-screen h-screen flex items-center justify-center flex-col gap-4">
<h1 class="text-3xl text-red-500 font-bold">Runes</h1>
<div class="text-xl font-bold">
{data.selected.someOption} ({data.selected.pageNum})
</div>
<div class="flex gap-2 items-center justify-center">
<button
class="border border-blue-500 p-2 rounded-lg text-blue-500"
onclick={() => {
data.selected.someOption = 'New Option value!';
}}
>
Change Option
</button>
<button
class="bg-blue-500 text-white p-2 rounded-lg"
onclick={() => {
data.selected.pageNum += 5;
changeURL();
}}
>
+5
</button>
</div>
</div>
Note: same +page.server.ts
After this I looked into what svetle-migrate
is doing to resolve this. So it replace reactive
label $:
with run
from svelte/legacy
. And this does nothing as they have to be declared with $state()
<script lang="ts">
import { run } from 'svelte/legacy';
import { goto } from '$app/navigation';
interface Props {
data: any;
}
let { data }: Props = $props();
let pageNum;
run(() => {
pageNum = data.selected.pageNum;
});
// Local state: sets to new option value from server when data changes
let selectedSomeOption;
run(() => {
selectedSomeOption = data.selected.someOption;
});
function changeURL() {
goto(`/?pageNum=${encodeURIComponent(pageNum)}`);
}
</script>
<div class="w-screen h-screen flex items-center justify-center flex-col gap-4">
<div class="text-xl font-bold">
{selectedSomeOption} ({pageNum})
</div>
<div class="flex gap-2 items-center justify-center">
<button
class="border border-blue-500 p-2 rounded-lg text-blue-500"
onclick={() => {
selectedSomeOption = 'New Option value!';
}}
>
Change Option
</button>
<button
class="bg-blue-500 text-white p-2 rounded-lg"
onclick={() => {
pageNum += 5;
changeURL();
}}
>
+5
</button>
</div>
</div>