Skip to content

Commit 45f18d5

Browse files
committed
fix(core): use detached scope to dispose state and stop watcher
1 parent 581f2b1 commit 45f18d5

File tree

1 file changed

+35
-41
lines changed

1 file changed

+35
-41
lines changed

packages/core/src/composables/useVueFlow.ts

Lines changed: 35 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { toRefs, tryOnScopeDispose } from '@vueuse/core'
22
import type { EffectScope } from 'vue'
3-
import { computed, getCurrentScope, inject, provide, reactive, watch } from 'vue'
3+
import { computed, effectScope, getCurrentScope, inject, provide, reactive, watch } from 'vue'
44
import { useActions, useGetters, useState } from '~/store'
55
import type { EdgeChange, FlowOptions, FlowProps, NodeChange, State, VueFlowStore } from '~/types'
66
import { VueFlow } from '~/context'
@@ -96,8 +96,6 @@ export function useVueFlow(options?: FlowProps): VueFlowStore {
9696

9797
let vueFlow: Injection
9898

99-
let isParentScope = false
100-
10199
/**
102100
* check if we can get a store instance through injections
103101
* this should be the regular way after initialization
@@ -131,47 +129,31 @@ export function useVueFlow(options?: FlowProps): VueFlowStore {
131129

132130
vueFlow = state
133131

134-
if (scope) {
135-
isParentScope = true
136-
137-
scope.run(() => {
138-
watch(
139-
state.applyDefault,
140-
(shouldApplyDefault) => {
141-
const nodesChangeHandler = (changes: NodeChange[]) => {
142-
state.applyNodeChanges(changes)
143-
}
144-
145-
const edgesChangeHandler = (changes: EdgeChange[]) => {
146-
state.applyEdgeChanges(changes)
147-
}
148-
149-
if (shouldApplyDefault) {
150-
state.onNodesChange(nodesChangeHandler)
151-
state.onEdgesChange(edgesChangeHandler)
152-
} else {
153-
state.hooks.value.nodesChange.off(nodesChangeHandler)
154-
state.hooks.value.edgesChange.off(edgesChangeHandler)
155-
}
156-
},
157-
{ immediate: true },
158-
)
159-
})
160-
}
161-
} else {
162-
// if composable was called with additional options after initialization, overwrite state with the options values
163-
if (options) {
164-
vueFlow.setState(options)
165-
}
166-
}
132+
const detachedScope = effectScope()
167133

168-
// always provide a fresh instance into context on call
169-
if (scope) {
170-
provide(VueFlow, vueFlow)
134+
detachedScope.run(() => {
135+
watch(
136+
state.applyDefault,
137+
(shouldApplyDefault) => {
138+
const nodesChangeHandler = (changes: NodeChange[]) => {
139+
state.applyNodeChanges(changes)
140+
}
171141

172-
scope.vueFlowId = vueFlow.id
142+
const edgesChangeHandler = (changes: EdgeChange[]) => {
143+
state.applyEdgeChanges(changes)
144+
}
145+
146+
if (shouldApplyDefault) {
147+
state.onNodesChange(nodesChangeHandler)
148+
state.onEdgesChange(edgesChangeHandler)
149+
} else {
150+
state.hooks.value.nodesChange.off(nodesChangeHandler)
151+
state.hooks.value.edgesChange.off(edgesChangeHandler)
152+
}
153+
},
154+
{ immediate: true },
155+
)
173156

174-
if (isParentScope) {
175157
// dispose of state values and storage entry
176158
tryOnScopeDispose(() => {
177159
if (vueFlow) {
@@ -184,8 +166,20 @@ export function useVueFlow(options?: FlowProps): VueFlowStore {
184166
}
185167
}
186168
})
169+
})
170+
} else {
171+
// if composable was called with additional options after initialization, overwrite state with the options values
172+
if (options) {
173+
vueFlow.setState(options)
187174
}
188175
}
189176

177+
// always provide a fresh instance into context on call
178+
if (scope) {
179+
provide(VueFlow, vueFlow)
180+
181+
scope.vueFlowId = vueFlow.id
182+
}
183+
190184
return vueFlow
191185
}

0 commit comments

Comments
 (0)