]> git.ipfire.org Git - thirdparty/vuejs/pinia.git/commitdiff
fix(subscribe): remove subscription when unmounted
authorEduardo San Martin Morote <posva13@gmail.com>
Sat, 10 Apr 2021 15:13:25 +0000 (17:13 +0200)
committerEduardo San Martin Morote <posva13@gmail.com>
Sat, 10 Apr 2021 15:13:25 +0000 (17:13 +0200)
__tests__/subscriptions.spec.ts
src/store.ts

index 0e4b9ca09a952235c4a60a41c2a4578dc83cf9e4..6d9a3c6dd531d7976201ee4f24f14a2d74399543 100644 (file)
@@ -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: `<p/>`,
+        },
+        { 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)
+    })
   })
 })
index 801906cdbde55bdde2b730ed83a944f94308ae24..6daaab6d4946e2274416a7c148577ce7db73954c 100644 (file)
@@ -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<Id extends string, S extends StateTree>(
       }
     )
 
-    return () => {
+    const removeSubscription = () => {
       const idx = subscriptions.indexOf(callback)
       if (idx > -1) {
         subscriptions.splice(idx, 1)
         stopWatcher()
       }
     }
+
+    if (getCurrentInstance()) {
+      onUnmounted(removeSubscription)
+    }
+
+    return removeSubscription
   }
 
   function $reset() {