Skip to content

Commit 5a2605e

Browse files
authored
fix(reactive): fix tracker unexpect update with strict-mode (#2526)
1 parent 0c5c6f1 commit 5a2605e

File tree

3 files changed

+35
-4
lines changed

3 files changed

+35
-4
lines changed

packages/reactive/src/__tests__/tracker.spec.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,30 @@ test('tracker recollect dependencies', () => {
6464
expect(fn).toBeCalledTimes(2)
6565
tracker.dispose()
6666
})
67+
68+
test('shared scheduler with multi tracker(mock react strict mode)', () => {
69+
const obs = observable<any>({})
70+
71+
const component = () => obs.value
72+
73+
const render = () => {
74+
tracker1.track(component)
75+
tracker2.track(component)
76+
}
77+
78+
const scheduler1 = jest.fn(() => {
79+
tracker2.track(component)
80+
})
81+
const scheduler2 = jest.fn(() => {
82+
tracker1.track(component)
83+
})
84+
const tracker1 = new Tracker(scheduler1, 'tracker1')
85+
const tracker2 = new Tracker(scheduler2, 'tracker2')
86+
87+
render()
88+
89+
obs.value = 123
90+
91+
expect(scheduler1).toBeCalledTimes(1)
92+
expect(scheduler2).toBeCalledTimes(1)
93+
})

packages/reactive/src/annotations/computed.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,21 +33,21 @@ export const computed: IComputed = createAnnotation(
3333

3434
function getGetter(target: any) {
3535
if (!target) {
36-
if (value?.get) return value?.get
36+
if (value && value.get) return value.get
3737
return value
3838
}
3939
const descriptor = Object.getOwnPropertyDescriptor(target, property)
40-
if (descriptor?.get) return descriptor.get
40+
if (descriptor && descriptor.get) return descriptor.get
4141
return getGetter(Object.getPrototypeOf(target))
4242
}
4343

4444
function getSetter(target: any) {
4545
if (!target) {
46-
if (value?.set) return value?.set
46+
if (value && value.set) return value.set
4747
return
4848
}
4949
const descriptor = Object.getOwnPropertyDescriptor(target, property)
50-
if (descriptor?.set) return descriptor.set
50+
if (descriptor && descriptor.set) return descriptor.set
5151
return getSetter(Object.getPrototypeOf(target))
5252
}
5353

packages/reactive/src/array.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export const toArray = (value: any) => {
88

99
export class ArraySet<T> {
1010
value: T[]
11+
batchDeleting = false
1112
constructor(value: T[] = []) {
1213
this.value = value
1314
}
@@ -23,6 +24,7 @@ export class ArraySet<T> {
2324
}
2425

2526
delete(item: T) {
27+
if (this.batchDeleting) return //批量删除时禁止单独删除,会影响计数执行器
2628
const index = this.value.indexOf(item)
2729
if (index > -1) {
2830
this.value.splice(index, 1)
@@ -38,12 +40,14 @@ export class ArraySet<T> {
3840

3941
forEachDelete(callback: (value: T) => void) {
4042
if (this.value.length === 0) return
43+
this.batchDeleting = true
4144
for (let index = 0; index < this.value.length; index++) {
4245
const item = this.value[index]
4346
this.value.splice(index, 1)
4447
callback(item)
4548
index--
4649
}
50+
this.batchDeleting = false
4751
}
4852

4953
clear() {

0 commit comments

Comments
 (0)