Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reactivity problem with fromStore() and objects #13077

Open
adiguba opened this issue Aug 30, 2024 · 4 comments
Open

Reactivity problem with fromStore() and objects #13077

adiguba opened this issue Aug 30, 2024 · 4 comments

Comments

@adiguba
Copy link
Contributor

adiguba commented Aug 30, 2024

Describe the bug

When using a fromStore() with a store that hold an object, the update of the object's fields is not reported in the store, which breaks reactivity.

Ex: something like this :

	// counter is a store containing an object like { value : 0 } 
	let count = fromStore(counter);
	
	function increment() {
		count.current.value++;
	}
  • In runes mode, the increment is done on the object, but there is no reactivity.
  • In non-runes mode, the increment is done on the object, but the reactivity is limited to the current component.

Reproduction

Demo here :

https://svelte-5-preview.vercel.app/#H4sIAAAAAAAACt1TXU-DMBT9Kw0xYcQ5fGZsifHdB_VNfGDdJauWlrSXqWn636WFsaHb1Jn44Auhp-d-nXNrgoJx0EHyYAKRlxAkwVVVBeMA3yp30GvgCM1Zy1pRh6SaKlbhPBMZsrKSCskdSgWkULIk4ST2p0kbGE4HtBx3ac3pIO1G3tYC9JDdgTtBabztRqRtH_F8-LtSHeKqf_zdvdzU3Ic0CpRyyQoGyyBBVYMd94JRWQsEtRXtSe8K1o1lyItimC84ENuN1c4Ra9erl0DAq-dSKbT7-rxk1keOiOH5AnhCwvsVkOuWEI7JOuc1JOTSRtNjnXpVjpvroURWyJoeiHLjz4xP0-ry2X3TN2p7uzpk8qRDN1aGRS2oS0mYoApKEDiKiHE3GZ5t2H6K83O_DPajuUu29lVNT_dSWDLy-kUJSRc1YlNCCsoZfZ6ZvpadD2s0kpohYtO4jXYzxq7WcR1z_LmOpwu4Zbr7drcPL1GGHLrtaQbtI0Zdzsjr-5UpnjyhtVIN_E1nhjEbe7YNRK0OX1i1p7Lzaw98gmndiz7hDRQ51795BP_GQyEv_t7GR_sOq2Eti6oGAAA=

  • The first two buttons use a store with Svelte 4 $ syntax, and incrementing the value is reactive in all components. 👍
  • The middle two buttons use fromStore() in runes mode, and incrementing the value is not reactive at all !
  • The last two buttons use fromStore() in non-runes mode, and incrementing the value is only reactive on the current component.

Logs

No response

System Info

REPL

Severity

annoyance

@7nik
Copy link

7nik commented Aug 30, 2024

#13076 (comment) and the next comment.

fromStore can be deeply reactive only by proxying the value, but it introduces reference issues, so it isn't a real solution.

@knejadshamsi
Copy link

I'm experiencing the same kind of issue with deeply nested reactivity when using fromStore. The value is correctly updated within the store but the change is not reactive and has no side effect (via $ or $effect)

@brunnerh
Copy link
Member

Workaround are:

  • Make the store value a $state object (example).
    - export const counter = writable({ label: 'The Counter', value: 0 });
    + const value = $state({ label: 'The Counter', value: 0 });
    + export const counter = writable(value);
  • Use full object assignments rather than mutations (example)
    - count.current.value++;
    + count.current = {
    + 	...count.current,
    + 	value: count.current.value + 1,
    + }
    ...or dummy assignments (example)
      count.current.value++;
    + count.current = count.current;

The $state approach is probably not always possible and also brittle if the store is writable (it could be assigned to a non-state object).

@knejadshamsi
Copy link

Thank you for the workaround @brunnerh . I also found another workaround. Here's a code snippet from my project testing out Svelte 5 preview:

const styleStore = fromStore(store).current
styleStore.fontSize = fontSizes[sliderValue]
store.set(styleStore)

It's not pretty. I'm pretty sure most of us use svelte for the syntax sugar

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants