Stores working with immutable data
See original GitHub issueUsing {#each…} with list/array from store updates all items from list while this can be avoided with immutable writable stores. I have expected that using <svelte:options immutable={true} />
would allow that (as per documentation “you never use mutable data, so the compiler can do simple referential equality checks to determine if values have changed” here https://svelte.dev/docs) but that’s not the case.
Here I have created sample https://github.com/daliusd/svelte_immutable_store app to demonstrate the problem. Run it, open dev tools and modify text or or add new item. You will see that afterUpdate
(https://github.com/daliusd/svelte_immutable_store/blob/ebc1bd4bd00a3d4a7687f5b13d484fd0135e6a1d/src/Item.svelte#L8) is called for each item even if we are updating only single item.
Here you can see https://github.com/daliusd/svelte_immutable_store/blob/master/src/store.js that I do not mutate my data thus references will not change.
Describe the solution you’d like
I think writable store should respect <svelte:options immutable={true} />
. I think this might be not enough however as internal svelte code might not handle lists/arrays properly. I have not looked that deep into Svelte’s code.
As well I think that by default svelte should create mutable stores (as it is now).
Describe alternatives you’ve considered
In some old version svelte supported immutable stores (see https://github.com/sveltejs/svelte/issues/1146). But I assume that was removed somewhere in progress. I think respecting global setting is better option as that would make app consistent and developer shouldn’t think if this store is mutable or immutable.
How important is this feature to you?
Modern browsers seems to handle updates that do not change anything quite well. E.g. if you change div’s position to the same value there will be no physical re-render. That makes this problem quite low priority IMHO.
From other side in one app of mine I do canvas re-render after update. That means I can not do re-render after each update because afterUpdate (or whatever is reactive) is called for all items even if I update only one item. I found workaround for this problem but it is second workaround I have to do in Svelte (bug is reported for first one already by other people).
Additional context
As well I see https://github.com/sveltejs/svelte/issues/2171 which explicitly states that stores are always mutable.
Lastly, in svelte’s source code I see those functions. That’s just my curiosity:
export function safe_not_equal(a, b) {
return a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function');
}
export function not_equal(a, b) {
return a != a ? b == b : a !== b;
}
Now I wonder why we have this part a != a ? b == b : a !== b
. a != a
is true only for NaN, that means this line overrides/inverts NaN behavior. Is that intentional?
Issue Analytics
- State:
- Created 4 years ago
- Comments:11
Thanks for example and your responses. I have learned something new (I think others as well).
https://svelte.dev/repl/a3637b5e83914c9b89f10c8cd422c747?version=3.12.1
It depends.
deep-state-observer
is couple times less expensive than cloning whole object if object has ten thousands of records, but when object is small cloning is faster (but with small object it doesn’t matter because two paradigms works real fast).Yeah you keeping it flat because it is hard to work with structured data when you want this data to be immutable 😄 Sometimes flattening your data can lead to ugly names of properties and not quite well organized data (of course it depends). I like to have things organized and structured into proper nodes (like folders). Normalized data from your link is of course better it is grouped well, but it is easier to access and set data with dot notation - less code 😛 With dot notation you can use immutable data too - on specific nodes so it is elastic - you are not replacing whole object - only specified items.
It depends on your project and on your habits. For me it is easier to use dot notation than writing a lot of actions for store (just for immutability). Those actions takes time and I think for simple data update this is an overhead. I think that dot notation is simpler and easier to refactor - you have path and you can always easily change path even with search and replace. But when you are working on live object you need to change a lot more code. Path here are kind of lenses in functional programing - you need to change string - not code itself.