Skip to content

Svelte 5 $state rune "hooks" improvement #13590

@sirkostya009

Description

@sirkostya009

Describe the problem

I am making a state class that has dozens of boolean switches that also need to be persisted to the local storage for convenience.

Initially I wanted to make a neat catch-all setter for all of those fields, but no matter what I did, be it iterating over keys inside constructor or creating a Proxy object, I couldn't get it to work, with the problem of former being having no keys to iterate over due to get-set nature of $state rune and the latter an error being thrown on Proxy object's property read stating Cannot read private member #state1 from an object whose class did not declare it.

Currently I manually write all of the state in a separate method.

// state.svelte.ts
export class State {
	constructor() {
		for (let i = 0; i < localStorage.length; ++i) {
			const key = localStorage.key(i);
			// @ts-ignore
			this[key] = Boolean(localStorage.getItem(key));
		}
	}

	state1 = $state(false);
	state2 = $state(true);
	state3 = $state(true);
	state4 = $state(true);
	state5 = $state(true);
	// ...

	persistToLocalStorage() {
		console.log('persisting');
		localStorage.setItem('state1', this.state1.toString());
		localStorage.setItem('state2', this.state2.toString());
		localStorage.setItem('state3', this.state3.toString());
		localStorage.setItem('state4', this.state4.toString());
		localStorage.setItem('state5', this.state5.toString());
		// ...
	}
}

// +page.svelte
$effect(() => st.persistToLocalStorage());

Describe the proposed solution

Making Proxy objects work would resolve this issue in the best way possible.

export function makeProxy() {
	return new Proxy(new State(), {
		set(target, p, newValue) {
			target[p] = newValue;
			localStorage.setItem(p, newValue);
			return true;
		}
	});
}

Importance

would make my life easier

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions