File tree Expand file tree Collapse file tree 2 files changed +33
-2
lines changed Expand file tree Collapse file tree 2 files changed +33
-2
lines changed Original file line number Diff line number Diff line change @@ -81,8 +81,12 @@ export class EffectScope {
81
81
stop ( fromParent ?: boolean ) {
82
82
if ( this . _active ) {
83
83
let i , l
84
- for ( i = 0 , l = this . effects . length ; i < l ; i ++ ) {
85
- this . effects [ i ] . stop ( )
84
+ // #5783
85
+ // effects will be changed when a watcher stoped.
86
+ // so we need to copy it for iteration.
87
+ const effectsToStop = this . effects . slice ( )
88
+ for ( i = 0 , l = effectsToStop . length ; i < l ; i ++ ) {
89
+ effectsToStop [ i ] . stop ( )
86
90
}
87
91
for ( i = 0 , l = this . cleanups . length ; i < l ; i ++ ) {
88
92
this . cleanups [ i ] ( )
Original file line number Diff line number Diff line change @@ -1126,6 +1126,33 @@ describe('api: watch', () => {
1126
1126
expect ( spy ) . toHaveBeenCalledTimes ( 2 )
1127
1127
} )
1128
1128
1129
+ test ( 'handle nested watcher stop properly' , ( ) => {
1130
+ let instance : ComponentInternalInstance
1131
+ const Comp = {
1132
+ setup ( ) {
1133
+ instance = getCurrentInstance ( ) !
1134
+ watch (
1135
+ ( ) => 1 ,
1136
+ ( val , oldVal , onCleanup ) => {
1137
+ const stop = watch (
1138
+ ( ) => 2 ,
1139
+ ( ) => { }
1140
+ )
1141
+ onCleanup ( stop )
1142
+ } ,
1143
+ { immediate : true }
1144
+ )
1145
+ return ( ) => ''
1146
+ }
1147
+ }
1148
+ const root = nodeOps . createElement ( 'div' )
1149
+ createApp ( Comp ) . mount ( root )
1150
+ expect ( instance ! . scope . effects . length ) . toBe ( 3 )
1151
+
1152
+ instance ! . scope . stop ( )
1153
+ expect ( instance ! . scope . effects [ 0 ] . active ) . toBe ( false )
1154
+ } )
1155
+
1129
1156
it ( 'watching sources: ref<any[]>' , async ( ) => {
1130
1157
const foo = ref ( [ 1 ] )
1131
1158
const spy = vi . fn ( )
You can’t perform that action at this time.
0 commit comments