I have a Svelte store activeAccountIndexStore
:
export const activeAccountIndexStore: Writable<number | "native" | null> =
writable(null);
The original value is null
but after some network activity it will be set to a specific number
or the string
'native'.
I also have a subscribe()
handler for the store, that is called from other Svelte components:
export const onChangeActiveAccount = (
activeAccountHandler: ActiveAccountHandler
) => {
activeAccountIndexStore.subscribe((newValue) => {
log(`➡️➡️➡️➡️➡️ activeAccountIndexStore new value`, newValue);
if (newValue !== null) {
const activeAccount = getActiveAccount();
activeAccountHandler(activeAccount);
}
});
};
The odd thing is, the subscribe()
change handler is being called repeatedly, even though the store has the same value in subsequent changes:
stores.ts:68 ➡️➡️➡️➡️➡️ activeAccountIndexStore new value null
stores.ts:68 ➡️➡️➡️➡️➡️ activeAccountIndexStore new value null
2stores.ts:68 ➡️➡️➡️➡️➡️ activeAccountIndexStore new value 0
stores.ts:68 ➡️➡️➡️➡️➡️ activeAccountIndexStore new value 0
stores.ts:68 ➡️➡️➡️➡️➡️ activeAccountIndexStore new value 0
stores.ts:68 ➡️➡️➡️➡️➡️ activeAccountIndexStore new value 0
stores.ts:68 ➡️➡️➡️➡️➡️ activeAccountIndexStore new value 0
MDNs Svelte docs state:
A store is an object with a subscribe() method that allows interested parties to be notified whenever the store value changes.
But the value is not changing in many of the cases above. I would have expected to see:
stores.ts:68 ➡️➡️➡️➡️➡️ activeAccountIndexStore new value null
stores.ts:68 ➡️➡️➡️➡️➡️ activeAccountIndexStore new value 0
Why does my Svelte store subscribe() get fired when the value hasn't changed?
CodePudding user response:
It has to do with re-evaluation of your Svelte components. If you're subscribing to a store inside a component, and instances of the component are being created and destroyed, the subscribe event will fire because the value is new for this instance of the component.
Re-evaluation of the component could happen if it gets unmounted, and re-mounted, or if the component is receiving new state.
A simple solution for this is to memoize the component state, eg do the .subscribe()
outside of the component.