From: Eduardo San Martin Morote Date: Sat, 10 Apr 2021 15:13:25 +0000 (+0200) Subject: fix(subscribe): remove subscription when unmounted X-Git-Tag: v2.0.0-alpha.13~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=10e1c3069a23f3a9c0d1e32cbc1fbb074709173e;p=thirdparty%2Fvuejs%2Fpinia.git fix(subscribe): remove subscription when unmounted --- diff --git a/__tests__/subscriptions.spec.ts b/__tests__/subscriptions.spec.ts index 0e4b9ca0..6d9a3c6d 100644 --- a/__tests__/subscriptions.spec.ts +++ b/__tests__/subscriptions.spec.ts @@ -1,4 +1,5 @@ import { createPinia, defineStore, setActivePinia } from '../src' +import { mount } from '@vue/test-utils' describe('Subscriptions', () => { const useStore = () => { @@ -53,6 +54,7 @@ describe('Subscriptions', () => { }) it('triggers subscribe only once', async () => { + setActivePinia(createPinia()) const s1 = useStore() const s2 = useStore() @@ -70,5 +72,45 @@ describe('Subscriptions', () => { expect(spy1).toHaveBeenCalledTimes(1) expect(spy2).toHaveBeenCalledTimes(1) }) + + it('removes on unmount', async () => { + const pinia = createPinia() + const spy1 = jest.fn() + const spy2 = jest.fn() + + const wrapper = mount( + { + setup() { + const s1 = useStore() + s1.$subscribe(spy1) + }, + template: `

`, + }, + { global: { plugins: [pinia] } } + ) + + const s1 = useStore() + const s2 = useStore() + + s2.$subscribe(spy2) + + expect(spy1).toHaveBeenCalledTimes(0) + expect(spy2).toHaveBeenCalledTimes(0) + + s1.name = 'Edu' + + expect(spy2).toHaveBeenCalledTimes(1) + expect(spy1).toHaveBeenCalledTimes(1) + + s1.$patch({ name: 'a' }) + expect(spy1).toHaveBeenCalledTimes(2) + expect(spy2).toHaveBeenCalledTimes(2) + + await wrapper.unmount() + + s1.$patch({ name: 'b' }) + expect(spy1).toHaveBeenCalledTimes(2) + expect(spy2).toHaveBeenCalledTimes(3) + }) }) }) diff --git a/src/store.ts b/src/store.ts index 801906cd..6daaab6d 100644 --- a/src/store.ts +++ b/src/store.ts @@ -1,4 +1,12 @@ -import { watch, computed, Ref, inject, getCurrentInstance, reactive } from 'vue' +import { + watch, + computed, + Ref, + inject, + getCurrentInstance, + reactive, + onUnmounted, +} from 'vue' import { StateTree, StoreWithState, @@ -135,13 +143,19 @@ function initStore( } ) - return () => { + const removeSubscription = () => { const idx = subscriptions.indexOf(callback) if (idx > -1) { subscriptions.splice(idx, 1) stopWatcher() } } + + if (getCurrentInstance()) { + onUnmounted(removeSubscription) + } + + return removeSubscription } function $reset() {