I am running into a error with reactive state in Svelte 5 with SvelteKit.
I've written a simple helper for syncing a state with remote data.
// $lib/remoteProxy.svelte.jsexport const remoteProxy = (val, fetcher) => { let proxy = $state(val); let loading = $state(false); const mutate = async (f) => { proxy = f(proxy) loading = true proxy = await fetcher() loading = false } return { proxy, mutate, loading }}
But when I import this into a page, this state is no longer reactive.
<script> import { remoteProxy } from '$lib/remoteProxy.svelte.js'; // sample response would be { records: RecordObject[], limit: 10, page: 1 } const remotePaginatedRecords = remoteProxy([], () => { fetch('https://paginated.api/'); }); const recordResponse = $derived(remotePaginatedRecords.proxy); const mutateRecords = remotePaginatedRecords.mutate; const handleCreateRecord = () => { mutateRecords((currentRecords) => { currentRecords.records.push({}); }); };</script>{#each recordResponse.records as record}<Record {record} />{/each}<button onclick={handleCreateRecord}>Create</button>
In this case, updating (appending, deleting, renaming, updating values) via mutate does not rerender the each clause.
On mutating the state, $inspect
reveals the remoteProxy proxy
state being updated, but inspecting the recordResponse
shows that it is only set initially, and not updated reactively when proxy
changes.I've tried variants of each object being $derived
, but nothing has worked so far.
The documents indicate that the state proxies in Svelte 5 are deep. Shouldn't this be forcing a new render?